<template>
  <div class="club-admin-dashboard">
    <!-- 添加消息通知组件 -->
    <transition-group name="message-slide" tag="div" class="message-notifications">
      <div v-for="notification in notifications" :key="notification.id" class="notification-item">
        <div class="notification-content" :class="notification.type.toLowerCase()">
          <el-icon class="notification-icon">
            <component :is="getNotificationIcon(notification.type)" />
          </el-icon>
          <div class="notification-info">
            <div class="notification-title">{{ notification.title }}</div>
            <div class="notification-message">{{ notification.content }}</div>
          </div>
        </div>
      </div>
    </transition-group>
    <el-container class="full-height">
      <el-header class="dashboard-header">
        <div class="header-title">社团管理系统 - 社团管理员端</div>
        <div class="header-user">
          <!-- 添加消息通知图标 -->
          <div class="message-notification" @click="handleMessageClick(null)">
            <el-badge :value="unreadMessageCount" :hidden="unreadMessageCount === 0" class="message-badge">
              <el-icon class="message-icon"><Bell /></el-icon>
            </el-badge>
          </div>
          <el-dropdown @command="handleCommand">
            <span class="user-info">
              <!-- 使用本地存储的 avatarUrl -->
              <el-avatar :size="35" :src="userInfo.avatarUrl" style="margin-right: 10px;"></el-avatar>
              <!-- 优先显示 real_name，否则显示 username -->
              <span class="username">{{ userInfo.real_name || userInfo.username }}</span>
              <el-icon class="el-icon--right" style="margin-left: 5px;"><arrow-down /></el-icon>
            </span>
            <template #dropdown>
              <el-dropdown-menu>
                <!-- 新增个人信息菜单项 -->
                <el-dropdown-item command="personalInfo">
                  <el-icon>
                    <User />
                  </el-icon>个人信息
                </el-dropdown-item>
                <el-dropdown-item command="logout">
                  <el-icon>
                    <SwitchButton />
                  </el-icon>退出登录
                </el-dropdown-item>
              </el-dropdown-menu>
            </template>
          </el-dropdown>
        </div>
      </el-header>

      <el-container class="main-container">
        <el-aside width="220px" class="sidebar-menu">
          <el-scrollbar>
            <el-menu :default-active="activeMenu" class="el-menu-vertical" @select="handleSelect"
              active-text-color="#fff" text-color="rgba(255, 255, 255, 0.7)" background-color="#001529">
              <el-menu-item index="club-info">
                <el-icon>
                  <School />
                </el-icon>
                <span>社团信息</span>
              </el-menu-item>
              <el-menu-item index="activity-management">
                <el-icon>
                  <Calendar />
                </el-icon>
                <span>活动管理</span>
              </el-menu-item>
              <el-menu-item index="member-management">
                <el-icon>
                  <User />
                </el-icon>
                <span>成员管理</span>
              </el-menu-item>
              <el-menu-item index="announcement-management">
                <el-icon>
                  <Bell />
                </el-icon>
                <span>公告管理</span>
              </el-menu-item>
              <!-- 新增消息接收菜单 -->
              <el-menu-item index="message-management">
                <el-icon>
                  <Message />
                </el-icon>
                <span>消息接收</span>
              </el-menu-item>
            </el-menu>
          </el-scrollbar>
        </el-aside>

        <el-main class="content-area">
          <!-- 社团信息部分 -->
          <div v-if="activeMenu === 'club-info'" class="content-section">
            <el-card class="box-card">
              <template #header>
                <div class="card-header">
                  <span>社团基本信息</span>
                  <el-button type="primary" @click="handleEditClubInfo">
                    <el-icon style="margin-right: 5px;"><Edit /></el-icon>编辑社团信息
                  </el-button>
                </div>
              </template>
              <el-descriptions :column="2" border label-class-name="desc-label" content-class-name="desc-content">
                <!-- 移除社团ID显示项 -->
                <el-descriptions-item label="社团名称">{{ clubInfo.clubName }}</el-descriptions-item>
                <el-descriptions-item label="社团描述" :span="2">{{ clubInfo.description }}</el-descriptions-item>
                <el-descriptions-item label="社团封面">
                  <el-image v-if="clubInfo.coverUrl" :src="clubInfo.coverUrl" fit="contain"
                    style="width: 150px; height: 150px; border-radius: 4px;" :preview-src-list="[clubInfo.coverUrl]"
                    hide-on-click-modal />
                  <span v-else>暂无封面</span>
                </el-descriptions-item>
                <el-descriptions-item label="创建时间">
                  {{ formatDate(clubInfo.createdAt) }}
                </el-descriptions-item>
                <el-descriptions-item label="社团状态">
                  <el-tag :type="getClubStatusType(clubInfo.status)">
                    {{ getClubStatusText(clubInfo.status) }}
                  </el-tag>
                </el-descriptions-item>
                <el-descriptions-item label="活动状态">
                  <el-tag
                    :type="clubInfo.activity_status === '正常' ? 'success' : (clubInfo.activity_status === '暂停活动' ? 'warning' : 'danger')">
                    {{ clubInfo.activity_status }}
                  </el-tag>
                </el-descriptions-item>
                <!-- 添加更多社团详细信息 -->
                <el-descriptions-item label="社团类别">{{ clubInfo.category || '未设置' }}</el-descriptions-item>
                <el-descriptions-item label="最大成员数">{{ clubInfo.maxMembers || '不限' }}</el-descriptions-item>
                <el-descriptions-item label="例会时间">{{ clubInfo.meetingTime || '未设置' }}</el-descriptions-item>
                <el-descriptions-item label="例会地点">{{ clubInfo.meetingLocation || '未设置' }}</el-descriptions-item>
                <el-descriptions-item label="联系人">{{ clubInfo.contactPerson || '未设置' }}</el-descriptions-item>
                <el-descriptions-item label="联系电话">{{ clubInfo.contactPhone || '未设置' }}</el-descriptions-item>
                <el-descriptions-item label="联系邮箱">{{ clubInfo.contactEmail || '未设置' }}</el-descriptions-item>
                <el-descriptions-item label="社团成就" :span="2">{{ clubInfo.achievements || '暂无成就' }}</el-descriptions-item>
                <el-descriptions-item label="社团规章制度" :span="2">{{ clubInfo.rules || '暂无规章制度' }}</el-descriptions-item>
              </el-descriptions>
            </el-card>
          </div>

          <!-- 活动管理部分 -->
          <div v-if="activeMenu === 'activity-management'" class="content-section">
            <el-card class="box-card">
              <template #header>
                <div class="card-header">
                  <div class="title-section">活动列表</div>
                  <div class="header-operations">
                    <div class="search-form">
                      <el-form :inline="true" :model="activityQueryForm">
                        <el-form-item style="margin-right: 8px;">
                          <el-select v-model="activityQueryForm.status" placeholder="活动状态" clearable
                            @clear="loadActivityList" style="width: 120px;">
                            <el-option label="全部" :value="null" />
                            <el-option label="未发布" :value="0" />
                            <el-option label="已发布" :value="1" />
                            <el-option label="已取消" :value="2" />
                            <el-option label="已延期" :value="3" />
                            <el-option label="已结束" :value="4" />
                          </el-select>
                        </el-form-item>
                        <el-form-item>
                          <el-input v-model="activityQueryForm.keyword" placeholder="活动名称/描述" clearable
                            @clear="loadActivityList" style="width: 200px;" />
                        </el-form-item>
                        <el-form-item>
                          <el-date-picker v-model="activityQueryForm.startTime" type="datetime" placeholder="开始时间"
                            clearable @clear="loadActivityList" style="width: 180px;" />
                        </el-form-item>
                        <el-form-item>
                          <el-date-picker v-model="activityQueryForm.endTime" type="datetime" placeholder="结束时间"
                            clearable @clear="loadActivityList" style="width: 180px;" />
                        </el-form-item>
                        <el-form-item>
                          <el-button type="primary" @click="loadActivityList">查询</el-button>
                          <el-button @click="resetActivityQuery">重置</el-button>
                        </el-form-item>
                        <el-form-item>
                          <el-button type="primary" @click="handleCreateActivity">
                            <el-icon style="margin-right: 5px;">
                              <CirclePlus />
                            </el-icon>创建新活动
                          </el-button>
                        </el-form-item>
                      </el-form>
                    </div>
                  </div>
                </div>
              </template>
              <el-table :data="activityList" style="width: 100%" v-loading="activityLoading" stripe @row-click="handleViewActivity">
                <el-table-column prop="title" label="活动名称" min-width="180" show-overflow-tooltip></el-table-column>
                <el-table-column prop="description" label="活动描述" min-width="200"
                  show-overflow-tooltip></el-table-column>
                <el-table-column prop="coverUrl" label="封面图" width="100" align="center">
                  <template #default="scope">
                    <el-image :src="scope.row.coverUrl" :preview-src-list="[scope.row.coverUrl]" fit="cover"
                      style="width: 50px; height: 50px; border-radius: 4px;" />
                  </template>
                </el-table-column>
                <el-table-column prop="start_time" label="开始时间" width="170">
                  <template #default="scope">{{ formatDate(scope.row.startTime) }}</template>
                </el-table-column>
                <el-table-column prop="end_time" label="结束时间" width="170">
                  <template #default="scope">{{ formatDate(scope.row.endTime) }}</template>
                </el-table-column>
                <el-table-column prop="maxParticipants" label="人数上限" width="100" align="center"></el-table-column>
                <el-table-column prop="status" label="活动状态" width="110" align="center">
                  <template #default="scope">
                    <el-tag :type="getActivityStatusType(scope.row.status)">
                      {{ getActivityStatusText(scope.row.status) }}
                    </el-tag>
                  </template>
                </el-table-column>
                <el-table-column prop="createdAt" label="创建时间" width="170">
                  <template #default="scope">{{ formatDate(scope.row.createdAt) }}</template>
                </el-table-column>
                <el-table-column label="操作" width="120" align="center">
                  <template #default="scope">
                    <el-button size="small" type="primary" plain @click.stop="handleRegistrations(scope.row)">
                      <el-icon style="margin-right: 4px;">
                        <View />
                      </el-icon>查看报名
                    </el-button>
                  </template>
                </el-table-column>
                <el-table-column label="操作" width="180" align="center" fixed="right">
                  <template #default="scope">
                    <el-button size="small" @click.stop="handleEditActivity(scope.row)" plain>
                      <el-icon style="margin-right: 4px;">
                        <EditPen />
                      </el-icon>编辑
                    </el-button>
                    <el-popconfirm title="确定删除此活动吗?" confirm-button-text="确定" cancel-button-text="取消"
                      @confirm="handleDeleteActivity(scope.row)">
                      <template #reference>
                        <el-button size="small" type="danger" plain>
                          <el-icon style="margin-right: 4px;">
                            <Delete />
                          </el-icon>删除
                        </el-button>
                      </template>
                    </el-popconfirm>
                  </template>
                </el-table-column>
              </el-table>
            </el-card>
          </div>

          <!-- 成员管理部分 -->
          <div v-if="activeMenu === 'member-management'" class="content-section">
            <el-card class="box-card">
              <template #header>
                <div class="card-header">
                  <span class="card-title">社团成员</span>
                  <div class="header-operations">
                    <div class="search-form">
                      <el-form :inline="true" :model="memberQueryForm">
                        <el-form-item>
                          <el-input v-model="memberQueryForm.keyword" placeholder="用户名/真实姓名" clearable
                            @clear="loadMemberList" style="width: 200px;" />
                        </el-form-item>
                        <el-form-item>
                          <el-date-picker v-model="memberQueryForm.startTime" type="datetime" placeholder="开始时间"
                            clearable @clear="loadMemberList" style="width: 180px;" />
                        </el-form-item>
                        <el-form-item>
                          <el-date-picker v-model="memberQueryForm.endTime" type="datetime" placeholder="结束时间" clearable
                            @clear="loadMemberList" style="width: 180px;" />
                        </el-form-item>
                        <el-form-item>
                          <el-select v-model="memberQueryForm.status" placeholder="成员状态" clearable
                            @clear="loadMemberList" style="width: 120px;">
                            <el-option label="正常" :value="0" />
                            <el-option label="已退出" :value="1" />
                          </el-select>
                        </el-form-item>
                        <el-form-item>
                          <el-button type="primary" @click="loadMemberList">查询</el-button>
                          <el-button @click="resetMemberQuery">重置</el-button>
                          <el-dropdown @command="handleExportCommand">
                            <el-button>
                              <el-icon style="margin-right: 5px;">
                                <Download />
                              </el-icon>批量导出<el-icon class="el-icon--right"><arrow-down /></el-icon>
                            </el-button>
                            <template #dropdown>
                              <el-dropdown-menu>
                                <el-dropdown-item command="xlsx">导出为 Excel</el-dropdown-item>
                                <el-dropdown-item command="txt">导出为 TXT</el-dropdown-item>
                                <el-dropdown-item command="csv">导出为 CSV</el-dropdown-item>
                              </el-dropdown-menu>
                            </template>
                          </el-dropdown>
                        </el-form-item>
                      </el-form>
                    </div>
                  </div>
                </div>
              </template>
              <el-table :data="memberList" style="width: 100%" v-loading="memberLoading" stripe>
                <el-table-column prop="user.avatarUrl" label="头像" width="80" align="center">
                  <template #default="scope">
                    <el-avatar :size="40" :src="scope.row.user?.avatarUrl"></el-avatar>
                  </template>
                </el-table-column>
                <el-table-column prop="user.username" label="用户名" width="150" show-overflow-tooltip></el-table-column>
                <el-table-column prop="user.realName" label="真实姓名" width="150" show-overflow-tooltip></el-table-column>
                <el-table-column prop="joinTime" label="加入时间" width="180">
                  <template #default="scope">{{ formatDate(scope.row.joinTime) }}</template>
                </el-table-column>
                <el-table-column prop="status" label="成员状态" width="120" align="center">
                  <template #default="scope">
                    <el-tag :type="scope.row.status === 0 ? 'success' : 'danger'">
                      {{ scope.row.status === 0 ? '正常' : '已退出' }}
                    </el-tag>
                  </template>
                </el-table-column>
                <el-table-column prop="user.phone" label="手机" width="140" show-overflow-tooltip></el-table-column>
                <el-table-column prop="user.email" label="邮箱" width="200" show-overflow-tooltip></el-table-column>
                <el-table-column label="操作" width="180" align="center" fixed="right">
                  <template #default="scope">
                    <el-popconfirm v-if="scope.row.status === 0" title="确定移除该成员吗?" confirm-button-text="确定"
                      cancel-button-text="取消" @confirm="handleRemoveMember(scope.row)">
                      <template #reference>
                        <el-button size="small" type="danger" plain>
                          <el-icon style="margin-right: 4px;">
                            <UserFilled />
                          </el-icon>移除
                        </el-button>
                      </template>
                    </el-popconfirm>
                  </template>
                </el-table-column>
              </el-table>
            </el-card>
          </div>

          <!-- 公告管理部分 -->
          <div v-if="activeMenu === 'announcement-management'" class="content-section">
            <el-card class="box-card">
              <template #header>
                <div class="card-header" style="display: flex; align-items: center; gap: 16px;">
                  <span style="font-size: 16px; font-weight: 500;">社团公告</span>
                  <el-form :inline="true" :model="announcementSearchForm" style="margin: 0; flex: 1;">
                    <el-form-item style="margin: 0 8px 0 0;">
                      <el-input v-model="announcementSearchForm.keyWords" placeholder="标题/内容" clearable
                        @clear="searchAnnouncements" style="width: 200px;"></el-input>
                    </el-form-item>
                    <el-form-item style="margin: 0 8px 0 0;">
                      <el-select v-model="announcementSearchForm.status" placeholder="状态" clearable
                        @clear="searchAnnouncements" style="width: 120px;">
                        <el-option label="全部" :value="null" />
                        <el-option label="已发布" :value="1" />
                        <el-option label="草稿" :value="0" />
                      </el-select>
                    </el-form-item>
                    <el-form-item style="margin: 0 8px 0 0;">
                      <el-button type="primary" @click="searchAnnouncements">查询</el-button>
                      <el-button @click="resetAnnouncementSearch">重置</el-button>
                    </el-form-item>
                  </el-form>
                  <div style="display: flex; gap: 8px;">
                    <el-button type="primary" @click="handleOpenCreateDraftDialog">
                      <el-icon style="margin-right: 5px;">
                        <DocumentAdd />
                      </el-icon>创建草稿
                    </el-button>
                    <el-button type="primary" @click="handleCreateAnnouncement">
                      <el-icon style="margin-right: 5px;">
                        <DocumentAdd />
                      </el-icon>发布新公告
                    </el-button>
                  </div>
                </div>
              </template>
              <el-table :data="announcementList" style="width: 100%" v-loading="announcementLoading" border stripe>
                <el-table-column type="index" label="序号" width="80" />
                <el-table-column prop="title" label="公告标题" width="200" />
                <el-table-column prop="content" label="公告内容" show-overflow-tooltip />
                <el-table-column prop="type" label="公告类型" width="100">
                  <template #default="scope">
                    <el-tag>{{ scope.row.type }}</el-tag>
                  </template>
                </el-table-column>
                <el-table-column prop="status" label="状态" width="100">
                  <template #default="scope">
                    <el-tag :type="scope.row.status === 1 ? 'success' : 'warning'">
                      {{ scope.row.status === 1 ? '已发布' : '草稿' }}
                    </el-tag>
                  </template>
                </el-table-column>
                <el-table-column prop="level" label="公告级别" width="100">
                  <template #default="scope">
                    <el-tag :type="scope.row.level === '系统级' ? 'danger' : 'warning'">{{ scope.row.level }}</el-tag>
                  </template>
                </el-table-column>
                <el-table-column prop="createdByName" label="发布人" width="120" />
                <el-table-column prop="createdAt" label="发布时间" width="180">
                  <template #default="scope">
                    {{ formatDate(scope.row.createdAt) }}
                  </template>
                </el-table-column>
                <!-- 新增阅读情况列 -->
                <el-table-column label="阅读情况" width="120" align="center">
                  <template #default="scope">
                    <span v-if="scope.row.status === 1">
                      已读 {{ scope.row.readCount || 0 }} / 未读 {{ scope.row.unreadCount || 0 }}
                    </span>
                    <span v-else>
                      仅草稿
                    </span>
                  </template>
                </el-table-column>
                <el-table-column label="操作" width="200" fixed="right">
                  <template #default="scope">
                    <el-button size="small" class="publish-btn"
                      @click="handleOpenPublishDialog('publish-draft', scope.row)" :disabled="scope.row.status === 1"
                      plain>发布</el-button>
                    <el-button size="small" class="delete-btn" @click="handleDeleteAnnouncement(scope.row)"
                      plain>删除</el-button>
                  </template>
                </el-table-column>
              </el-table>
              <div class="pagination">
                <el-pagination :current-page="announcementCurrentPage" :page-size="announcementPageSize"
                  :page-sizes="[10, 20, 30, 50]" :total="announcementTotal"
                  layout="total, sizes, prev, pager, next, jumper" @size-change="handleAnnouncementSizeChange"
                  @current-change="handleAnnouncementCurrentChange" />
              </div>
            </el-card>
          </div>

          <!-- 活动报名详情部分 -->
          <div v-if="activeMenu === 'registration-detail'" class="content-section">
            <el-card class="box-card">
              <template #header>
                <div class="card-header">
                  <span>{{ currentActivityTitle }} 的报名列表</span>
                  <div class="header-operations">
                    <div class="batch-actions" v-if="selectedRegistrationIds.length > 0">
                      <el-button type="success" size="small" @click="handleReviewRegistration(null, 1)" plain>
                        <el-icon style="margin-right: 4px;"><Select /></el-icon>批量通过
                      </el-button>
                      <el-button type="danger" size="small" @click="handleReviewRegistration(null, 2)" plain>
                        <el-icon style="margin-right: 4px;">
                          <CloseBold />
                        </el-icon>批量拒绝
                      </el-button>
                      <el-dropdown @command="handleExportRegistrationCommand">
                        <el-button type="primary" size="small" plain>
                          <el-icon style="margin-right: 4px;">
                            <Download />
                          </el-icon>导出选中<el-icon class="el-icon--right"><arrow-down /></el-icon>
                        </el-button>
                        <template #dropdown>
                          <el-dropdown-menu>
                            <el-dropdown-item command="xlsx">导出为 Excel</el-dropdown-item>
                            <el-dropdown-item command="txt">导出为 TXT</el-dropdown-item>
                            <el-dropdown-item command="csv">导出为 CSV</el-dropdown-item>
                          </el-dropdown-menu>
                        </template>
                      </el-dropdown>
                      <span class="selected-count">已选择 {{ selectedRegistrationIds.length }} 项</span>
                    </div>
                    <el-button @click="activeMenu = 'activity-management'" plain>
                      <el-icon style="margin-right: 5px;">
                        <Back />
                      </el-icon>返回活动列表
                    </el-button>
                  </div>
                </div>
              </template>
              
              <!-- 添加审核结果显示区域 -->
              <div class="review-result-display">
                <el-descriptions title="报名统计" :column="2" border>
                  <el-descriptions-item label="最大参与人数">
                    {{ reviewResult.maxParticipants }}
                  </el-descriptions-item>
                  <el-descriptions-item label="当前报名人数">
                    {{ reviewResult.currentApplicants }}
                  </el-descriptions-item>
                  <el-descriptions-item label="剩余名额">
                    {{ reviewResult.remainingSpots }}
                  </el-descriptions-item>
                  <el-descriptions-item label="审核通过总人数">
                    {{ reviewResult.reviewedCount }}
                  </el-descriptions-item>
                </el-descriptions>
              </div>

              <!-- 将原对话框中的表格内容移到此处 -->
              <el-table :data="registrationList" style="width: 100%" stripe
                @selection-change="handleRegistrationSelectionChange">
                <!-- 复选框列 -->
                <el-table-column type="selection" width="55" />
                <el-table-column prop="avatarUrl" label="头像" width="80" align="center">
                  <template #default="scope">
                    <el-avatar :size="40" :src="scope.row.avatarUrl"></el-avatar>
                  </template>
                </el-table-column>
                <el-table-column prop="username" label="用户名" min-width="120" show-overflow-tooltip></el-table-column>
                <el-table-column prop="realName" label="真实姓名" min-width="120" show-overflow-tooltip></el-table-column>
                <el-table-column prop="phone" label="手机" width="140"></el-table-column>
                <el-table-column prop="registrationTime" label="报名时间" width="180">
                  <template #default="scope">{{ formatDate(scope.row.registrationTime) }}</template>
                </el-table-column>
                <el-table-column prop="registrationStatus" label="审核状态" width="100" align="center">
                  <template #default="scope">
                    <el-tag :type="getRegistrationStatusType(scope.row.registrationStatus)">
                      {{ getRegistrationStatusText(scope.row.registrationStatus) }}
                    </el-tag>
                  </template>
                </el-table-column>
                <!-- 审核操作列 -->
                <el-table-column label="操作" width="180" align="center" fixed="right">
                  <template #default="scope">
                    <el-button size="small" type="success" @click="handleReviewRegistration(scope.row, 1)"
                      :disabled="scope.row.registrationStatus !== 0" plain><el-icon
                        style="margin-right: 4px;"><Select /></el-icon>通过</el-button>
                    <el-button size="small" type="danger" @click="handleReviewRegistration(scope.row, 2)"
                      :disabled="scope.row.registrationStatus !== 0" plain><el-icon style="margin-right: 4px;">
                        <CloseBold />
                      </el-icon>拒绝</el-button>
                  </template>
                </el-table-column>
              </el-table>

            </el-card>
          </div>

          <!-- 消息接收部分 -->
          <div v-if="activeMenu === 'message-management'" class="content-section">
            <el-card class="box-card">
              <template #header>
                <div class="card-header">
                  <span>消息列表</span>
                  <div class="message-filters">
                    <el-radio-group v-model="messageFilter" size="small">
                      <el-radio-button label="all">全部</el-radio-button>
                      <el-radio-button label="unread">未读</el-radio-button>
                      <el-radio-button label="read">已读</el-radio-button>
                    </el-radio-group>
                  </div>
                  <!-- 添加一键已读按钮 -->
                  <el-button type="primary" size="small" @click="handleMarkAllAsRead" :disabled="unreadMessageCount === 0">
                    <el-icon style="margin-right: 4px;"><Reading /></el-icon>一键已读
                  </el-button>
                </div>
              </template>
              
              <!-- 消息列表 -->
              <div class="message-list">
                <!-- 模拟数据 -->
                <div v-for="message in messages" :key="message.id" 
                     :class="['message-card', { 'unread': !message.readStatus }]"
                     @click="handleMessageClick(message)">
                  <div class="message-icon" :class="message.type">
                    <el-icon v-if="message.type === 'announcement'"><Bell /></el-icon>
                    <el-icon v-else-if="message.type === 'activity'"><Calendar /></el-icon>
                    <el-icon v-else><Message /></el-icon>
                  </div>
                  <div class="message-content">
                    <div class="message-header">
                      <span class="message-title">{{ message.title }}</span>
                      <el-tag size="small" :type="message.type === 'announcement' ? 'warning' : 'success'">
                        {{ message.type === 'announcement' ? '公告' : '活动' }}
                      </el-tag>
                    </div>
                    <div class="message-body">{{ message.content }}</div>
                    <div class="message-footer">
                      <span class="message-time">{{ formatDate(message.createdAt) }}</span>
                      <span v-if="!message.readStatus" class="unread-badge">未读</span>
                    </div>
                  </div>
                </div>
              </div>
            </el-card>
          </div>

        </el-main>
      </el-container>
    </el-container>

    <!-- 创建/编辑活动 对话框 -->
    <el-dialog v-model="activityDialogVisible" :title="activityDialogType === 'create' ? '创建新活动' : '编辑活动'" width="50%"
      draggable>
      <el-form :model="activityForm" label-width="100px" ref="activityFormRef">
        <el-form-item label="活动标题" prop="title">
          <el-input v-model="activityForm.title" placeholder="请输入活动标题"></el-input>
        </el-form-item>
        <el-form-item label="活动描述" prop="description">
          <el-input type="textarea" :rows="3" v-model="activityForm.description" placeholder="请输入活动描述"></el-input>
        </el-form-item>
        <el-form-item label="封面图" prop="file">
          <div style="display: flex; flex-direction: column; align-items: flex-start;">
            <img v-if="previewUrl" :src="previewUrl" class="activity-cover-preview" style="margin-bottom: 10px;" />
            <el-upload class="upload-demo" action="#" :auto-upload="false" :on-change="handleFileUpload" :limit="1"
              accept="image/*" :show-file-list="false">
              <template #trigger>
                <el-button type="primary">选择文件</el-button>
              </template>
            </el-upload>
            <div class="el-upload__tip">请上传图片文件，且不超过 5MB</div>
          </div>
        </el-form-item>
        <el-form-item label="开始时间" prop="startTime">
          <el-date-picker v-model="activityForm.startTime" type="datetime" placeholder="选择开始时间"
            format="YYYY-MM-DD HH:mm:ss" value-format="YYYY-MM-DD HH:mm:ss"></el-date-picker>
        </el-form-item>
        <el-form-item label="结束时间" prop="endTime">
          <el-date-picker v-model="activityForm.endTime" type="datetime" placeholder="选择结束时间"
            format="YYYY-MM-DD HH:mm:ss" value-format="YYYY-MM-DD HH:mm:ss"></el-date-picker>
        </el-form-item>
        <el-form-item label="人数上限" prop="maxParticipants">
          <el-input-number v-model="activityForm.maxParticipants" :min="0" placeholder="请输入人数上限"></el-input-number>
        </el-form-item>
        <el-form-item label="活动状态" prop="status">
          <el-select v-model="activityForm.status" placeholder="请选择活动状态">
            <el-option label="未发布" :value="0" />
            <el-option label="已发布" :value="1" />
            <el-option label="已取消" :value="2" />
            <el-option label="已延期" :value="3" />
            <el-option label="已结束" :value="4" />
          </el-select>
        </el-form-item>
      </el-form>
      <template #footer>
        <el-button @click="activityDialogVisible = false">取消</el-button>
        <el-button type="primary" @click="submitActivityForm">确定</el-button>
      </template>
    </el-dialog>

    <!-- 发布公告对话框 -->
    <el-dialog v-model="announcementDialogVisible" :title="dialogTitle" width="50%">
      <el-form :model="announcementForm" label-width="100px">
        <el-form-item label="公告标题" required>
          <el-input v-model="announcementForm.title" />
        </el-form-item>
        <el-form-item label="公告内容" required>
          <el-input v-model="announcementForm.content" type="textarea" :rows="4" />
        </el-form-item>
        <el-form-item label="公告类型" required>
          <el-select v-model="announcementForm.type" placeholder="请选择公告类型">
            <el-option label="通知" value="NOTICE" />
            <el-option label="活动" value="EVENT" />
            <el-option label="系统" value="SYSTEM" />
          </el-select>
        </el-form-item>
        <el-form-item label="公告级别">
          <span class="form-item-static-text">社团级</span>
        </el-form-item>
        <el-form-item label="发送方式" required>
          <el-radio-group v-model="announcementForm.sendType" @change="handleSendTypeChange">
            <el-radio label="broadcast">广播给社团的所有成员</el-radio>
            <el-radio label="multiple">发送给指定用户</el-radio>
          </el-radio-group>
        </el-form-item>

        <!-- 当选择发送给指定用户时显示用户选择 -->
        <el-form-item v-if="announcementForm.sendType === 'multiple'" label="选择用户">
          <el-select v-model="announcementForm.receiverIds" multiple filterable remote :remote-method="searchUsers"
            placeholder="请输入用户名/真实姓名搜索" style="width: 100%" v-loading="userSearchLoading">
            <el-option v-for="user in userSearchList" :key="user.id"
              :label="user.username + (user.realName ? '（' + user.realName + '）' : '') + ' | ' + (user.role || '普通用户')"
              :value="user.id">
              <div
                style="display: flex; align-items: center; justify-content: flex-start; padding: 0 6px; min-width: 180px;">
                <span style="font-size: 15px; color: #333; flex: 1; text-align: left;">
                  {{ user.username }}<span v-if="user.realName">（{{ user.realName }}）</span>
                </span>
                <el-tag size="small" :type="getRoleTagType(user.role)"
                  style="margin-left: 8px; min-width: 60px; text-align: center;">
                  {{ user.role || '普通用户' }}
                </el-tag>
              </div>
            </el-option>
          </el-select>
        </el-form-item>
      </el-form>
      <template #footer>
        <span class="dialog-footer">
          <el-button @click="announcementDialogVisible = false">取消</el-button>
          <el-button type="primary" @click="saveAnnouncement">保存</el-button>
        </span>
      </template>
    </el-dialog>

    <!-- 创建公告草稿对话框 -->
    <el-dialog v-model="createDraftDialogVisible" title="创建公告草稿" width="50%">
      <el-form :model="createDraftForm" label-width="100px">
        <el-form-item label="公告标题" required>
          <el-input v-model="createDraftForm.title" />
        </el-form-item>
        <el-form-item label="公告内容" required>
          <el-input v-model="createDraftForm.content" type="textarea" :rows="4" />
        </el-form-item>
        <el-form-item label="公告类型" required>
          <el-select v-model="createDraftForm.type" placeholder="请选择公告类型">
            <el-option label="通知" value="NOTICE" />
            <el-option label="活动" value="EVENT" />
            <el-option label="系统" value="SYSTEM" />
          </el-select>
        </el-form-item>
        <el-form-item label="公告级别">
          <span class="form-item-static-text">社团级</span>
        </el-form-item>
      </el-form>
      <template #footer>
        <span class="dialog-footer">
          <el-button @click="createDraftDialogVisible = false">取消</el-button>
          <el-button type="primary" @click="saveDraft">保存草稿</el-button>
        </span>
      </template>
    </el-dialog>

    <!-- 编辑社团信息对话框 -->
    <el-dialog v-model="clubInfoDialogVisible" title="编辑社团信息" width="60%">
      <el-form :model="clubInfoForm" label-width="120px" ref="clubInfoFormRef">
        <el-form-item label="社团名称" prop="clubName">
          <el-input v-model="clubInfoForm.clubName" placeholder="请输入社团名称"></el-input>
        </el-form-item>
        <el-form-item label="社团描述" prop="clubDescription">
          <el-input type="textarea" :rows="3" v-model="clubInfoForm.clubDescription" placeholder="请输入社团描述"></el-input>
        </el-form-item>
        <el-form-item label="社团封面" prop="file">
          <div style="display: flex; flex-direction: column; align-items: flex-start;">
            <img v-if="clubLogoPreviewUrl" :src="clubLogoPreviewUrl" class="club-logo-preview" style="margin-bottom: 10px;" />
            <el-upload class="upload-demo" action="#" :auto-upload="false" :on-change="handleClubLogoUpload" :limit="1"
              accept="image/*" :show-file-list="false">
              <template #trigger>
                <el-button type="primary">选择文件</el-button>
              </template>
            </el-upload>
            <div class="el-upload__tip">请上传图片文件，且不超过 5MB</div>
          </div>
        </el-form-item>
        <el-form-item label="活动状态" prop="activityStatus">
          <el-select v-model="clubInfoForm.activityStatus" placeholder="请选择活动状态">
            <el-option label="正常" value="正常" />
            <el-option label="暂停活动" value="暂停活动" />
          </el-select>
        </el-form-item>
        <el-form-item label="社团类别" prop="clubCategory">
          <el-input v-model="clubInfoForm.clubCategory" placeholder="请输入社团类别"></el-input>
        </el-form-item>
        <el-form-item label="最大成员数" prop="maxMembers">
          <el-input-number v-model="clubInfoForm.maxMembers" :min="0" placeholder="请输入最大成员数"></el-input-number>
        </el-form-item>
        <el-form-item label="例会时间" prop="meetingTime">
          <el-input v-model="clubInfoForm.meetingTime" placeholder="请输入例会时间，如：每周五晚上7点"></el-input>
        </el-form-item>
        <el-form-item label="例会地点" prop="meetingLocation">
          <el-input v-model="clubInfoForm.meetingLocation" placeholder="请输入例会地点"></el-input>
        </el-form-item>
        <el-form-item label="联系人" prop="contactPerson">
          <el-input v-model="clubInfoForm.contactPerson" placeholder="请输入联系人姓名"></el-input>
        </el-form-item>
        <el-form-item label="联系邮箱" prop="contactEmail">
          <el-input v-model="clubInfoForm.contactEmail" placeholder="请输入联系邮箱"></el-input>
        </el-form-item>
        <el-form-item label="社团成就" prop="clubAchievements">
          <el-input type="textarea" :rows="3" v-model="clubInfoForm.clubAchievements" placeholder="请输入社团成就"></el-input>
        </el-form-item>
        <el-form-item label="社团规章制度" prop="clubRegulations">
          <el-input type="textarea" :rows="3" v-model="clubInfoForm.clubRegulations" placeholder="请输入社团规章制度"></el-input>
        </el-form-item>
      </el-form>
      <template #footer>
        <span class="dialog-footer">
          <el-button @click="clubInfoDialogVisible = false">取消</el-button>
          <el-button type="primary" @click="submitClubInfoForm">保存</el-button>
        </span>
      </template>
    </el-dialog>

    <!-- 活动详情对话框 -->
    <el-dialog v-model="activityDetailVisible" title="活动详情" width="70%" class="activity-detail-dialog">
      <div v-if="currentActivity" class="activity-detail">
        <div class="activity-header">
          <h2>{{ currentActivity.title }}</h2>
          <el-tag :type="getActivityStatusType(currentActivity.status)">
            {{ getActivityStatusText(currentActivity.status) }}
          </el-tag>
        </div>
        
        <div class="activity-content">
          <div class="activity-cover">
            <el-image :src="currentActivity.coverUrl" fit="cover" :preview-src-list="[currentActivity.coverUrl]" />
          </div>
          
          <div class="activity-info">
            <el-descriptions :column="2" border>
              <el-descriptions-item label="活动描述" :span="2">{{ currentActivity.description }}</el-descriptions-item>
              <el-descriptions-item label="开始时间">{{ formatDate(currentActivity.startTime) }}</el-descriptions-item>
              <el-descriptions-item label="结束时间">{{ formatDate(currentActivity.endTime) }}</el-descriptions-item>
              <el-descriptions-item label="人数上限">{{ currentActivity.maxParticipants || '不限' }}</el-descriptions-item>
              <el-descriptions-item label="创建时间">{{ formatDate(currentActivity.createdAt) }}</el-descriptions-item>
            </el-descriptions>
          </div>
        </div>

        <!-- 评论区域 -->
        <div class="activity-comments">
          <h3>评论区</h3>
          
          <!-- 发表评论 -->
          <div class="comment-form">
            <el-input
              v-model="newComment"
              type="textarea"
              :rows="3"
              placeholder="写下你的评论..."
              :maxlength="500"
              show-word-limit
            />
            <el-button type="primary" @click="submitComment" :disabled="!newComment.trim()">
              发表评论
            </el-button>
          </div>

          <!-- 评论列表 -->
          <div class="comment-list">
            <recursive-comment
              v-for="comment in comments"
              :key="comment.id"
              :comment="comment"
              :level="0"
              @submit-reply="handleNestedReply"
            />
          </div>
        </div>
      </div>
    </el-dialog>

    <!-- 个人信息编辑对话框 -->
    <el-dialog v-model="personalInfoDialogVisible" title="编辑个人信息" width="50%">
      <el-form :model="personalInfoForm" label-width="100px" ref="personalInfoFormRef">
        <el-form-item label="用户名">
          <el-input v-model="personalInfoForm.username" disabled></el-input> <!-- 用户名通常不可修改 -->
        </el-form-item>
        <el-form-item label="真实姓名" prop="realName">
          <el-input v-model="personalInfoForm.realName"></el-input>
        </el-form-item>
        <el-form-item label="手机" prop="phone">
          <el-input v-model="personalInfoForm.phone"></el-input>
        </el-form-item>
        <el-form-item label="邮箱" prop="email">
          <el-input v-model="personalInfoForm.email"></el-input>
        </el-form-item>
        <el-form-item label="身份证号" prop="idCard">
          <el-input v-model="personalInfoForm.idCard"></el-input>
        </el-form-item>
        <el-form-item label="头像" prop="avatarFile">
          <div style="display: flex; flex-direction: column; align-items: flex-start;">
            <el-avatar :size="80" :src="personalInfoAvatarPreviewUrl" style="margin-bottom: 10px;"></el-avatar>
            <el-upload class="upload-demo" action="#" :auto-upload="false" :on-change="handlePersonalInfoAvatarUpload" :limit="1" accept="image/*" :show-file-list="false">
              <template #trigger>
                <el-button type="primary">选择新头像</el-button>
              </template>
            </el-upload>
            <div class="el-upload__tip">请上传图片文件，且不超过 5MB</div>
          </div>
        </el-form-item>
      </el-form>
      <template #footer>
        <span class="dialog-footer">
          <el-button @click="personalInfoDialogVisible = false">取消</el-button>
          <el-button type="primary" @click="submitPersonalInfoForm">保存</el-button>
        </span>
      </template>
    </el-dialog>

    <!-- 添加审核结果对话框 -->
    <el-dialog
      v-model="reviewResultDialogVisible"
      title="审核结果"
      width="400px"
      center
    >
      <div class="review-result-content">
        <el-descriptions :column="1" border>
          <el-descriptions-item label="最大参与人数">
            {{ reviewResult.maxParticipants }}
          </el-descriptions-item>
          <el-descriptions-item label="当前报名人数">
            {{ reviewResult.currentApplicants }}
          </el-descriptions-item>
          <el-descriptions-item label="剩余名额">
            {{ reviewResult.remainingSpots }}
          </el-descriptions-item>
          <el-descriptions-item label="审核通过总人数">
            {{ reviewResult.reviewedCount }}
          </el-descriptions-item>
        </el-descriptions>
      </div>
      <template #footer>
        <span class="dialog-footer">
          <el-button type="primary" @click="reviewResultDialogVisible = false">
            确定
          </el-button>
        </span>
      </template>
    </el-dialog>

  </div>
</template>

<script setup>
import { ref, onMounted, reactive, computed, onBeforeUnmount, watch, nextTick, toRaw } from 'vue'
import { useRouter } from 'vue-router'
import { ElMessage, ElMessageBox } from 'element-plus'
import {
  School, Calendar, User, Bell, ArrowDown, SwitchButton, Edit, EditPen, Delete, Plus,
  CirclePlus, View, Select, CloseBold, UserFilled, DocumentAdd, Back, Download,
  Search, ArrowLeft, Message, Reading
} from '@element-plus/icons-vue'
import axios from 'axios'
import dayjs from 'dayjs'
import { Client } from '@stomp/stompjs'
import SockJS from 'sockjs-client'
// 导入 RecursiveComment 组件
import RecursiveComment from '../components/RecursiveComment.vue'

// 配置axios基础URL
axios.defaults.baseURL = 'http://localhost:8080/LZ'
axios.defaults.withCredentials = true

const router = useRouter()
const activeMenu = ref('club-info')

// WebSocket相关状态
const stompClient = ref(null)
const connected = ref(false)
const receivedMessages = ref([]) // 存储从WebSocket接收的原始消息，用于展示通知等
const messages = ref([]) // 存储用于列表展示的消息数据
const shownAnnouncementIds = ref(new Set())

// 初始化WebSocket连接
const initWebSocket = () => {
  const userId = JSON.parse(localStorage.getItem('userInfo'))?.id
  if (!userId) {
    console.error('无法获取用户ID，WebSocket连接失败')
    return
  }

  const socket = new SockJS('http://localhost:8080/LZ/ws')
  stompClient.value = new Client({
    webSocketFactory: () => socket,
    debug: (str) => {
      console.log('STOMP: ' + str)
    },
    reconnectDelay: 5000,
    heartbeatIncoming: 4000,
    heartbeatOutgoing: 4000,
    connectHeaders: {
      'user': userId.toString()
    }
  })

  stompClient.value.onConnect = () => {
    console.log('已连接到WebSocket服务器')
    console.log('当前用户ID:', userId)
    connected.value = true

    // 订阅广播消息
    stompClient.value.subscribe('/topic/broadcast', onMessageReceived)

    // 订阅私聊消息
    stompClient.value.subscribe('/user/queue/private', onMessageReceived)

    // 订阅群发消息
    // stompClient.value.subscribe('/topic/group/*', onMessageReceived)

    // 添加连接成功的消息
    const connectMessage = {
      from: 'System',
      to: [userId],
      content: 'WebSocket连接成功',
      type: 'system',
      timestamp: Date.now()
    }
    messages.value.unshift(connectMessage)
  }

  stompClient.value.onStompError = (frame) => {
    console.error('STOMP错误:', frame)
    connected.value = false
  }

  stompClient.value.onWebSocketError = (event) => {
    console.error('WebSocket错误:', event)
    connected.value = false
  }

  stompClient.value.onWebSocketClose = (event) => {
    console.log('WebSocket连接关闭:', event)
    connected.value = false
  }

  stompClient.value.activate()
}

// 处理接收到的消息
const onMessageReceived = (payload) => {
  const message = JSON.parse(payload.body)
  console.log('收到消息:', message)
  console.log('接收到的完整消息对象:', JSON.stringify(message, null, 2))

  // 创建一个包含临时ID的通知项
  const notificationItem = {
    ...message,
    id: Date.now() + Math.random() // 使用时间戳和随机数作为临时ID
  };

  // 添加消息到通知列表
  notifications.value.push(notificationItem);

  // 立即更新未读消息计数（假设新收到的消息默认为未读）
  if (notificationItem.readStatus === undefined || notificationItem.readStatus === 0) {
     unreadMessageCount.value++;
  }

  // 3秒后移除通知
  setTimeout(() => {
    // 根据临时ID移除对应的通知项
    notifications.value = notifications.value.filter(n => n.id !== notificationItem.id);

    // 刷新消息列表，这会重新从后端获取消息并更新未读计数，确保最终一致性
    loadMessages();
  }, 3000);

  // 如果是公告类型的消息，显示通知 (这个 ElMessage 提示是额外的，和上面的通知列表是两回事)
  // 为了避免重复提示，可以根据 type 进行区分或者只保留其中一种通知方式
  if (message.type === 'ANNOUNCEMENT' || message.type === 'NOTICE') {
     // showAnnouncement(message); // 如果您希望保留 ElMessage 提示，可以取消注释这行
  }


  // 立即刷新消息列表，确保显示最新消息
  // 由于 setTimeout 里面也会调用 loadMessages，这里的立即调用可以根据需要保留或移除
  // 如果希望通知出现的同时立即更新列表，就保留。如果希望通知消失后再更新列表，就移除。
  // 为了确保实时性，我建议保留这里的调用。
  loadMessages();
}

// 展示公告消息并去重 (这个函数对应 ElMessage 提示，与上面的通知列表区分开)
const showAnnouncement = (announcement) => {
  if (!announcement.id) return
  if (shownAnnouncementIds.value.has(announcement.id)) return
  shownAnnouncementIds.value.add(announcement.id)
  ElMessage({
    message: `收到新公告：${announcement.title}`,
    type: 'info',
    duration: 5000
  })
}

// 断开WebSocket连接
const disconnectWebSocket = () => {
  if (stompClient.value) {
    stompClient.value.deactivate()
    connected.value = false
  }
}

// 在组件挂载时初始化WebSocket连接
onMounted(async () => {
  await checkClubAdminRole()
  await loadClubInfo()
  if (clubInfo.value.id) {
    await loadDataForActiveMenu(activeMenu.value)
  }
  initWebSocket() // 初始化WebSocket连接
  // 加载消息列表
  await loadMessages()
})

// 在组件卸载前断开WebSocket连接
onBeforeUnmount(() => {
  disconnectWebSocket()
})

// 用户信息相关
// 修改：直接从本地存储解析完整的 userInfo JSON 对象
const userInfo = ref(JSON.parse(localStorage.getItem('userInfo')) || {
  username: '管理员',
  avatarUrl: 'https://cube.elemecdn.com/3/7c/3ea6beec64369c2642b92c6726f1epng.png', // 默认头像
  real_name: '' // 增加 real_name 字段，确保结构一致
});

// 新增：个人信息编辑相关状态
const personalInfoDialogVisible = ref(false);
const personalInfoFormRef = ref(null);
const personalInfoForm = ref({
  userId: null, // 用于标识要修改哪个用户
  username: '',
  realName: '',
  phone: '',
  email: '',
  idCard: '', // 新增身份证号字段
  avatarFile: null // 用于存储新的头像文件
});
const personalInfoAvatarPreviewUrl = ref(''); // 用于显示头像预览
// 新增：存储原始个人信息，用于比较是否修改
const originalPersonalInfo = ref({
    realName: '',
    phone: '',
    email: '',
    idCard: '', // 新增身份证号字段
    avatarUrl: ''
});

// 社团信息相关
const clubInfo = ref({
  id: null,
  name: '',
  description: '',
  coverUrl: '',
  status: null, // 0:审核中，1:已通过，2:已拒绝
  createdAt: '',
  activity_status: '正常' // 社团活动状态
})

// 活动管理相关
const activityList = ref([])
const activityLoading = ref(false)
const activityQueryForm = reactive({
  keyword: '',
  startTime: null,
  endTime: null,
  status: undefined, // 修改为undefined，这样在请求时如果未选择状态则为null
  clubId: null  // 这里需要从当前登录用户的社团信息中获取
})

// 报名管理相关
const registrationDialogVisible = ref(false)
const registrationList = ref([])
const currentActivityId = ref(null)
const currentActivityTitle = ref('')
const selectedRegistrationIds = ref([])

// 成员管理相关
const memberList = ref([])
const memberLoading = ref(false)
const memberQueryForm = reactive({
  keyword: '',
  startTime: null,
  endTime: null,
  status: null
})

// 公告管理相关
const announcementList = ref([])
const announcementTotal = ref(0)
const announcementCurrentPage = ref(1)
const announcementPageSize = ref(10)
const announcementLoading = ref(false)
const announcementSearchForm = ref({
  keyWords: '',
  status: null
})

const originalActivity = ref({})

// 公告管理相关
const announcementDialogVisible = ref(false)
const dialogTitle = ref('发布新公告')
const announcementForm = ref({
  title: '',
  content: '',
  type: 'NOTICE',
  level: '社团级',
  sendType: 'broadcast',
  receiverIds: []
})

// 成员搜索相关
const memberSearchList = ref([])
const memberSearchLoading = ref(false)

// 用户搜索相关
const userSearchList = ref([])
const userSearchLoading = ref(false)

// 初始化加载
onMounted(async () => {
  await checkClubAdminRole() // 确保在加载任何数据前检查角色
  await loadClubInfo()
  // 根据activeMenu加载对应数据
  if (clubInfo.value.id) { // 确保clubId获取后再加载关联数据
    await loadDataForActiveMenu(activeMenu.value)
  }
  initWebSocket() // 初始化WebSocket连接
  // 加载消息列表
  await loadMessages()
})

const loadDataForActiveMenu = async (menuKey) => {
  if (menuKey === 'activity-management') {
    await loadActivityList()
  } else if (menuKey === 'member-management') {
    await loadMemberList()
  } else if (menuKey === 'announcement-management') {
    await loadAnnouncementList()
  } else if (menuKey === 'message-management') {
    await loadMessages()
  }
}

// 检查社团管理员角色
const checkClubAdminRole = async () => {
  const role = localStorage.getItem('role')
  if (role !== '社团管理员') {
    ElMessage.error('无权访问社团管理员页面，请以社团管理员身份登录。')
    // 可以考虑更平滑的登出，或直接跳转
    localStorage.removeItem('token')
    localStorage.removeItem('userInfo')
    localStorage.removeItem('role')
    localStorage.removeItem('userId')
    localStorage.removeItem('username')
    localStorage.removeItem('avatarUrl')

    router.push('/login')
    return Promise.reject(new Error('Access Denied')) // 阻止后续加载
  }
  return Promise.resolve()
}

// 加载社团信息 
const loadClubInfo = async () => {
  try {
    const storedUserInfo = JSON.parse(localStorage.getItem('userInfo'))
    const userId = storedUserInfo?.id
    if (!userId) {
      ElMessage.error('无法获取用户ID，请重新登录')
      router.push('/login')
      return
    }

    const response = await axios.get(`/activities/selectClubsTest/${userId}`)

    if (response.data.code === 200) {
      // 将status从字符串转换为数字
      const clubData = response.data.data;
      clubInfo.value = {
        ...clubData,
        status: parseInt(clubData.status), // 将status转换为数字
        activity_status: clubData.activityStatus || '正常', // 注意这里后端返回的是activityStatus
        clubName: clubData.clubName // 添加clubName字段
      }

      localStorage.setItem('clubInfo', JSON.stringify(response.data.data))
    } else {
      ElMessage.error(response.data.message || '获取社团信息失败')
    }
  } catch (error) {
    console.error('加载社团信息出错:', error)
    ElMessage.error('获取社团信息失败，请稍后重试')
  }
}

// 格式化日期
const formatDate = (dateString) => {
  if (!dateString) return 'N/A'
  const date = new Date(dateString)
  return date.toLocaleString('zh-CN', {
    year: 'numeric', month: '2-digit', day: '2-digit',
    hour: '2-digit', minute: '2-digit', second: '2-digit'
  })
}

// 活动相关方法
const loadActivityList = async () => {
  try {
    activityLoading.value = true
    if (!activityQueryForm.clubId) {
      activityQueryForm.clubId = clubInfo.value.id
    }

    const queryParams = {
      keyword: activityQueryForm.keyword || null,
      startTime: activityQueryForm.startTime || null,
      endTime: activityQueryForm.endTime || null,
      status: activityQueryForm.status === undefined ? null : activityQueryForm.status, // 修改状态处理逻辑
      clubId: clubInfo.value.clubId
    }

    const response = await axios.post('/activities/search', queryParams, {
      headers: {
        'Content-Type': 'application/json'
      }
    })
    if (response.data.code === 200) {
      activityList.value = response.data.data
    } else {
      ElMessage.error(response.data.message || '获取活动列表失败')
    }
  } catch (error) {
    console.error('加载活动列表失败:', error)
    ElMessage.error('加载活动列表失败')
  } finally {
    activityLoading.value = false
  }
}

// 活动表单相关
const activityDialogVisible = ref(false)
const activityDialogType = ref('create')
const activityFormRef = ref(null)
const activityForm = ref({
  title: '',
  description: '',
  startTime: '',
  endTime: '',
  maxParticipants: 0,
  clubId: null
})

const uploadFile = ref(null)

// 处理创建活动按钮点击
const handleCreateActivity = () => {
  activityDialogType.value = 'create'
  activityForm.value = {
    title: '',
    description: '',
    startTime: '',
    endTime: '',
    maxParticipants: 0,
    clubId: clubInfo.value.clubId,
    file: null
  }
  activityDialogVisible.value = true
}

// 处理文件上传
const handleFileUpload = (file) => {
  if (file) {
    const isImage = file.raw.type.startsWith('image/')
    const isLt5M = file.raw.size / 1024 / 1024 < 5
    if (!isImage) {
      ElMessage.error('只能上传图片文件！')
      return false
    }
    if (!isLt5M) {
      ElMessage.error('图片大小不能超过 5MB！')
      return false
    }
    uploadFile.value = file.raw
    previewUrl.value = URL.createObjectURL(file.raw)
    return true
  }
  return false
}
// 对话框关闭时清理预览
const handleDialogClose = () => {
  previewUrl.value = ''
  uploadFile.value = null
}

// 提交活动表单
const submitActivityForm = async () => {
  try {
    const formData = new FormData()
    let fileToSend = null
    if (activityDialogType.value === 'edit') {
      fileToSend = uploadFile.value ? uploadFile.value : null
    } else {
      if (!uploadFile.value) {
        ElMessage.error('请上传活动封面图片')
        return
      }
      fileToSend = uploadFile.value
    }
    // 保证 file 字段一定存在
    if (fileToSend) {
      formData.append('file', fileToSend)
    } else {
      formData.append('file', new Blob([], { type: 'application/octet-stream' }), '')
    }

    let requestObj = null
    if (activityDialogType.value === 'edit') {
      requestObj = buildUpdateRequest()
    } else {
      requestObj = {
        title: activityForm.value.title,
        description: activityForm.value.description,
        startTime: activityForm.value.startTime,
        endTime: activityForm.value.endTime,
        maxParticipants: activityForm.value.maxParticipants,
        clubId: activityForm.value.clubId,
        status: activityForm.value.status
      }
    }
    formData.append('request', new Blob([JSON.stringify(requestObj)], { type: 'application/json' }))

    const url = activityDialogType.value === 'create' ? '/activities/create' : '/activities/update'
    // 打印传递给后端的信息
    console.log('活动API请求数据:', url, requestObj)
    const response = await axios.post(url, formData, {
      headers: { 'Content-Type': 'multipart/form-data' }
    })

    if (response.data.code === 200) {
      ElMessage.success(activityDialogType.value === 'create' ? '活动创建成功' : '活动更新成功')
      activityDialogVisible.value = false
      loadActivityList()
    } else {
      ElMessage.error(response.data.message || '操作失败')
    }
  } catch (error) {
    console.error('操作失败:', error)
    ElMessage.error('操作失败: ' + error.message)
  }
}
// 添加预览URL的响应式变量
const previewUrl = ref('')
const handleEditActivity = (activity) => {
  activityDialogType.value = 'edit'
  activityForm.value = {
    id: activity.id,
    title: activity.title,
    description: activity.description,
    startTime: dayjs(activity.startTime).format('YYYY-MM-DD HH:mm:ss'),
    endTime: dayjs(activity.endTime).format('YYYY-MM-DD HH:mm:ss'),
    maxParticipants: activity.maxParticipants,
    clubId: activity.clubId,
    status: activity.status
  }
  originalActivity.value = { ...activityForm.value, coverUrl: activity.coverUrl }
  previewUrl.value = activity.coverUrl || ''
  uploadFile.value = null
  activityDialogVisible.value = true
}

const buildUpdateRequest = () => {
  const req = {}
  req.id = activityForm.value.id
  req.title = activityForm.value.title !== originalActivity.value.title ? activityForm.value.title : null
  req.description = activityForm.value.description !== originalActivity.value.description ? activityForm.value.description : null
  req.startTime = activityForm.value.startTime !== originalActivity.value.startTime ? activityForm.value.startTime : null
  req.endTime = activityForm.value.endTime !== originalActivity.value.endTime ? activityForm.value.endTime : null
  req.maxParticipants = activityForm.value.maxParticipants !== originalActivity.value.maxParticipants ? activityForm.value.maxParticipants : null
  req.status = activityForm.value.status !== originalActivity.value.status ? activityForm.value.status : null
  // clubId 必须始终传递
  req.clubId = activityForm.value.clubId
  return req
}

const handleDeleteActivity = async (activity) => {
  // 这个函数现在只处理删除传入的单个 'activity' 对象
  // 它不再需要检查 selectedActivityIds

  ElMessageBox.confirm(
    // 删除单个活动的确认消息
    `确定删除活动 "${activity.title}" 吗?`,
    '提示',
    {
      confirmButtonText: '确定',
      cancelButtonText: '取消',
      type: 'warning',
    }
  ).then(async () => {
    try {
      // 使用 DELETE 方法，并将单个活动 ID 作为 params 发送
      const response = await axios.delete('/activities/delete', {
        params: {
          ids: activity.id // 发送单个 ID
        }
      });

      if (response.data.code === 200) {
        ElMessage.success('活动删除成功'); // 单个删除的成功消息
        // 不需要在这里清空 selectedActivityIds，因为这是单个删除

        await loadActivityList(); // 重新加载列表
      } else {
        ElMessage.error(response.data.message || '删除活动失败'); // 单个删除的失败消息
      }
    } catch (error) {
      console.error('删除活动失败:', error); // 记录单个删除的特定错误
      ElMessage.error('删除活动网络错误');
    }
  }).catch(() => {
    ElMessage.info('已取消删除'); // 取消消息
  });
};

// 报名管理方法
const handleRegistrations = async (activity) => {
  currentActivityId.value = activity.id
  currentActivityTitle.value = activity.title
  activeMenu.value = 'registration-detail'
  selectedRegistrationIds.value = []
  await loadRegistrations(activity.id)
}

const loadRegistrations = async (activityId) => {
  try {
    // 加载报名列表
    const response = await axios.get(`/activities/registration/${activityId}`);
    if (response.data.code === 200) {
      registrationList.value = response.data.data;
    } else {
      ElMessage.error(response.data.message || '获取报名列表失败');
    }

    // --- 新增：加载审核统计信息 ---
    const statsResponse = await axios.get('/activities/getApplicants', {
      params: { activityId: activityId }
    });

    if (statsResponse.data.code === 200) {
      const result = statsResponse.data.data;
      reviewResult.value = {
        maxParticipants: result.maxParticipants,
        currentApplicants: result.currentApplicants,
        remainingSpots: Math.max(0, result.remainingSpots), // 确保剩余名额不会显示负数
        reviewedCount: result.reviewedCount,
      };
    } else {
      console.error('获取报名统计信息失败:', statsResponse.data.message);
      // 可以选择清空统计信息或显示错误状态
      reviewResult.value = {
        maxParticipants: 0,
        currentApplicants: 0,
        remainingSpots: 0,
        reviewedCount: 0,
      };
      // ElMessage.error(statsResponse.data.message || '获取报名统计信息失败'); // 如果需要弹窗提示
    }
    // --- 新增结束 ---

  } catch (error) {
    console.error('加载报名列表或统计信息失败:', error);
    ElMessage.error('加载报名信息网络错误');
    registrationList.value = [];
    reviewResult.value = {
      maxParticipants: 0,
      currentApplicants: 0,
      remainingSpots: 0,
      reviewedCount: 0,
    };
  }
};

// 处理表格选择变化（报名管理表格）
const handleRegistrationSelectionChange = (selection) => {
  selectedRegistrationIds.value = selection.map(item => item.userId);
};

// 处理审核操作（适配单个或批量）
const handleReviewRegistration = async (registration, newStatus) => {
  let userIdsToReview = [];
  let confirmMessage = '';
  let successMessage = '';
  let errorMessage = '';

  if (selectedRegistrationIds.value.length > 0 && !registration) {
    userIdsToReview = selectedRegistrationIds.value;
    confirmMessage = `确定审核选中的 ${userIdsToReview.length} 条报名吗?`;
    successMessage = '批量审核操作成功';
    errorMessage = '批量审核失败';
  } else if (registration) {
    userIdsToReview = [registration.userId];
    confirmMessage = `确定审核用户 "${registration.username}" 的报名吗?`;
    successMessage = '审核操作成功';
    errorMessage = '审核失败';
  } else {
    ElMessage.warning('请选择要审核的报名记录');
    return;
  }

  const allSelectedArePending = userIdsToReview.every((userId) => {
    const registration = registrationList.value.find((reg) => reg.userId === userId);
    return registration && registration.registrationStatus === 0;
  });

  if (!allSelectedArePending) {
    ElMessage.warning('只能审核待审核状态的报名记录');
    return;
  }

  ElMessageBox.confirm(confirmMessage, '提示', {
    confirmButtonText: '确定',
    cancelButtonText: '取消',
    type: 'warning',
  })
    .then(async () => {
      try {
        const response = await axios.put('/activities/reviewRegistrations', {
          userIds: userIdsToReview,
          status: newStatus,
          activityId: currentActivityId.value,
        });

        if (response.data.code === 200) {
          ElMessage.success(successMessage);
          selectedRegistrationIds.value = [];

          // 处理审核结果数据，并更新 reviewResult 响应式变量
          const result = response.data.data;
          reviewResult.value = {
            maxParticipants: result.maxParticipants,
            currentApplicants: result.currentApplicants,
            remainingSpots: Math.max(0, result.remainingSpots), // 确保剩余名额不会显示负数
            reviewedCount: result.reviewedCount,
          };

          // 刷新当前活动的报名列表，这也会触发页面重新渲染使用最新的 reviewResult
          await loadRegistrations(currentActivityId.value); // 修改：仍然调用 loadRegistrations，它现在会同时更新列表和统计

          // 可以在这里添加一个轻量级的提示，或者完全依赖 ElMessage.success

        } else {
          ElMessage.error(response.data.message || errorMessage);
        }
      } catch (error) {
        console.error(errorMessage + ':', error);
        ElMessage.error(errorMessage + '网络错误');
      }
    })
    .catch(() => {
      ElMessage.info('已取消操作');
    });
};

// 成员管理方法
const loadMemberList = async () => {
  if (!clubInfo.value.id) return;
  memberLoading.value = true
  try {
    const response = await axios.post('/activities/selectClubsUser', {
      clubId: clubInfo.value.id,
      keyword: memberQueryForm.keyword || null,
      startTime: memberQueryForm.startTime || null,
      endTime: memberQueryForm.endTime || null,
      status: memberQueryForm.status || null
    })
    if (response.data.code === 200) {
      memberList.value = response.data.data.map(member => ({
        id: member.id,
        userId: member.userId,
        joinTime: member.joinTime,
        status: member.status,
        user: {
          username: member.username,
          avatarUrl: member.avatarUrl,
          realName: member.realName,
          phone: member.phone,
          email: member.email
        }
      }))
    } else {
      ElMessage.error(response.data.message || '获取成员列表失败')
    }
  } catch (error) {
    console.error('获取成员列表失败:', error)
    ElMessage.error('获取成员列表网络错误')
    memberList.value = []
  } finally {
    memberLoading.value = false
  }
}

// 重置成员查询条件
const resetMemberQuery = () => {
  Object.assign(memberQueryForm, {
    keyword: '',
    startTime: null,
    endTime: null,
    status: null
  })
  loadMemberList()
}

// 批量导出成员
const handleExportCommand = async (command) => {
  ElMessage.info(`正在导出 ${command} 格式文件，请稍候...`);

  try {
    // 构建请求参数，包含查询条件和导出格式
    const exportParams = {
      ...memberQueryForm,
      clubId: clubInfo.value.id, // 确保clubId存在
      format: command // 导出格式 (excel, txt, csv)
    };

    // 调用后端导出接口
    const response = await axios.post('/activities/export', exportParams, {
      responseType: 'blob' // 告诉axios响应是一个文件流
    });

    // 处理文件下载
    const blob = new Blob([response.data], { type: response.headers['content-type'] });
    const link = document.createElement('a');
    link.href = URL.createObjectURL(blob);

    // 尝试从响应头获取文件名，否则使用默认文件名
    const contentDisposition = response.headers['content-disposition'];
    let filename = `社团成员列表.${command}`;
    if (contentDisposition) {
      // 尝试匹配 UTF-8 编码的文件名 (RFC 6266)
      const utf8FilenameMatch = contentDisposition.match(/filename\*=UTF-8''([^;\n]*)/i);
      if (utf8FilenameMatch && utf8FilenameMatch[1]) {
        try {
          filename = decodeURIComponent(utf8FilenameMatch[1]);
        } catch (e) {
          console.error('Failed to decode UTF-8 filename', e);
          // Fallback to standard filename if UTF-8 decoding fails
          const standardFilenameMatch = contentDisposition.match(/filename="?([^"\n]*)"?/i);
          if (standardFilenameMatch && standardFilenameMatch[1]) {
            filename = standardFilenameMatch[1];
          }
        }
      } else {
        // 如果没有 UTF-8 编码的文件名，尝试匹配标准文件名
        const standardFilenameMatch = contentDisposition.match(/filename="?([^"\n]*)"?/i);
        if (standardFilenameMatch && standardFilenameMatch[1]) {
          filename = standardFilenameMatch[1];
        }
      }
    }
    link.download = filename;
    link.click();

    // 清理
    URL.revokeObjectURL(link.href);
    ElMessage.success('文件导出成功');

  } catch (error) {
    console.error('批量导出失败:', error);
    // 根据后端返回的错误格式进行处理，例如后端返回JSON格式的错误信息
    if (error.response && error.response.data) {
      // 尝试读取blob作为文本，以便解析JSON错误信息
      const reader = new FileReader();
      reader.onload = (e) => {
        try {
          const errorData = JSON.parse(e.target.result);
          ElMessage.error(errorData.message || '批量导出失败');
        } catch (parseError) {
          console.error('解析错误响应失败:', parseError);
          ElMessage.error('批量导出失败，服务器返回未知错误');
        }
      };
      // 确保 error.response.data 是 Blob 类型，然后再读取
      if (error.response.data instanceof Blob) {
        reader.readAsText(error.response.data);
      } else {
        ElMessage.error('批量导出失败，无法解析服务器错误信息');
      }

    } else {
      ElMessage.error('批量导出网络错误');
    }
  }
};
const handleRemoveMember = async (member) => {
  try {
    const newStatus = member.status === 0 ? 1 : 0;
    console.log(member)
    const removeMemberDto = {
      adminID: JSON.parse(localStorage.getItem('userInfo')).id,
      clubID: clubInfo.value.id,
      deleUserID: member.userId,
      status: newStatus.toString() // 转换为字符串
    }

    const response = await axios.post('/activities/removeMember', removeMemberDto)
    if (response.data.code === 200) {
      ElMessage.success(newStatus === 1 ? '成员已移除' : '成员已恢复')
      await loadMemberList() // 重新加载列表
    } else {
      ElMessage.error(response.data.message || '操作失败')
    }
  } catch (error) {
    console.error('操作失败:', error)
    ElMessage.error('操作网络错误')
  }
}

// 公告管理方法
const loadAnnouncementList = async () => {
  announcementLoading.value = true
  try {
    const response = await axios.post('/activities/selectClubsAnnouncement', {
      pageNum: announcementCurrentPage.value,
      pageSize: announcementPageSize.value,
      keyWords: announcementSearchForm.value.keyWords,
      status: announcementSearchForm.value.status,
      clubAdminId: JSON.parse(localStorage.getItem('userInfo')).id
    })
    if (response.data.code === 200) {
      announcementList.value = response.data.data.list || []
      announcementTotal.value = response.data.data.total || 0

      // --- 新增：获取已发布公告的阅读数量 ---
      const publishedAnnouncementIds = announcementList.value
        .filter(announcement => announcement.status === 1)
        .map(announcement => announcement.id);

      if (publishedAnnouncementIds.length > 0) {
        try {
          const readCountsResponse = await axios.post('/activities/getAnnouncementReadCounts', {
            announcementIds: publishedAnnouncementIds
          });

          if (readCountsResponse.data.code === 200 && readCountsResponse.data.data && readCountsResponse.data.data.messageCounts) {
            const messageCounts = readCountsResponse.data.data.messageCounts;

            // 将阅读量数据合并到公告列表中
            announcementList.value.forEach(announcement => {
              if (announcement.status === 1 && messageCounts[announcement.id]) {
                // 确保后端返回的ID是数字或可以转换为字符串匹配Map的键
                const countData = messageCounts[announcement.id.toString()];
                if (countData) {
                    announcement.readCount = countData.readCount;
                    announcement.unreadCount = countData.unreadCount;
                } else {
                    // 如果Map中没有该公告的统计数据，可能意味着无人阅读，设置为0
                    announcement.readCount = 0;
                    announcement.unreadCount = 0;
                }
              } else if (announcement.status === 1) { // 对于已发布但没有统计数据的公告，设置为0
                  announcement.readCount = 0;
                  announcement.unreadCount = 0;
              }
            });
             console.log('公告列表合并阅读量后:', announcementList.value); // 调试日志
          } else {
            console.warn('获取公告阅读量成功但数据格式不正确或为空:', readCountsResponse.data);
            // 可以在这里设置一个默认值或者显示加载失败
          }
        } catch (readCountsError) {
          console.error('获取公告阅读量失败:', readCountsError);
          // 可以在这里设置一个默认值或者显示加载失败，不中断主列表加载
          ElMessage.warning('部分公告阅读量加载失败');
        }
      }
      // --- 新增结束 ---

    } else {
      ElMessage.error(response.data.message || '获取公告列表失败')
      announcementList.value = []
      announcementTotal.value = 0
    }
  } catch (error) {
    console.error('获取公告列表失败:', error)
    ElMessage.error('获取公告列表网络错误')
    announcementList.value = []
    announcementTotal.value = 0
  } finally {
    announcementLoading.value = false
  }
}

const handleAnnouncementSizeChange = (val) => {
  announcementPageSize.value = val
  announcementCurrentPage.value = 1
  loadAnnouncementList()
}
const handleAnnouncementCurrentChange = (val) => {
  announcementCurrentPage.value = val
  loadAnnouncementList()
}
const searchAnnouncements = () => {
  announcementCurrentPage.value = 1
  loadAnnouncementList()
}
const resetAnnouncementSearch = () => {
  announcementSearchForm.value = {
    keyWords: '',
    status: null
  }
  announcementCurrentPage.value = 1
  loadAnnouncementList()
}
//发布新公告
const handleCreateAnnouncement = () => {
  announcementForm.value = {
    title: '',
    content: '',
    type: 'NOTICE',
    level: '社团级',
    sendType: 'broadcast',
    receiverIds: []
  }
  dialogTitle.value = '发布新公告'
  announcementDialogVisible.value = true
}


const handleViewAnnouncement = (announcement) => { ElMessage.info(`查看公告: ${announcement.title} (待实现)`) }
const handleEditAnnouncement = (announcement) => { ElMessage.info(`编辑公告: ${announcement.title} (待实现)`) }
const handleDeleteAnnouncement = async (announcement) => {
  try {
    const response = await axios.delete(`/api/club-admin/announcements/${announcement.id}`)
    if (response.data.code === 200) {
      ElMessage.success('公告删除成功')
      await loadAnnouncementList() // 重新加载列表
    } else {
      ElMessage.error(response.data.message || '删除公告失败')
    }
  } catch (error) {
    console.error('删除公告失败:', error)
    ElMessage.error('删除公告网络错误')
  }
}

// 状态显示相关
const getClubStatusType = (status) => { // 社团创建状态
  if (status === 1) return 'success' // 已通过
  if (status === 0) return 'warning' // 审核中
  if (status === 2) return 'danger'  // 已拒绝
  return 'info'
}
const getClubStatusText = (status) => {
  if (status === 1) return '已通过'
  if (status === 0) return '审核中'
  if (status === 2) return '已拒绝'
  return '未知状态'
}

const getActivityStatusType = (status) => {
  const statusMap = {
    '0': 'info',    // 未发布
    '1': 'success', // 已发布
    '2': 'danger',  // 已取消
    '3': 'warning', // 已延期
    '4': 'info'     // 已结束
  }
  return statusMap[status] || 'info'
}

const getActivityStatusText = (status) => {
  const statusMap = {
    '0': '未发布',
    '1': '已发布',
    '2': '已取消',
    '3': '已延期',
    '4': '已结束'
  }
  return statusMap[status] || '未知状态'
}

// 报名状态显示相关方法
const getRegistrationStatusType = (status) => { // 报名状态
  // 0:待审核，1:已通过，2:已拒绝
  if (status === 1) return 'success'
  if (status === 0) return 'warning'
  if (status === 2) return 'danger'
  return 'info'
}
const getRegistrationStatusText = (status) => {
  if (status === 1) return '已通过'
  if (status === 0) return '待审核'
  if (status === 2) return '已拒绝'
  return '未知'
}

// 菜单选择
const resetActivityQuery = () => {
  const clubId = activityQueryForm.clubId // 保存当前的 clubId
  Object.assign(activityQueryForm, {
    keyword: '',
    startTime: null,
    endTime: null,
    status: null,
    clubId: clubId // 重置时保留 clubId
  })
  loadActivityList()
}

const handleSelect = async (key) => {
  activeMenu.value = key
  if (clubInfo.value.id) { // 确保社团信息已加载
    await loadDataForActiveMenu(key)
  } else if (key !== 'club-info') {
    // 如果社团信息未加载，且切换到依赖社团信息的菜单，提示先加载社团信息或进行错误处理
    ElMessage.warning('请等待社团信息加载完成或检查社团信息是否正确获取。');
  }
}

// 用户操作
const handleCommand = async (command) => {
  if (command === 'personalInfo') {
    // 获取当前的用户信息
    const currentUserInfo = userInfo.value;

    if (currentUserInfo) {
        // 填充表单数据
        personalInfoForm.value = {
            userId: currentUserInfo.id,
            username: currentUserInfo.username,
            realName: currentUserInfo.real_name,
            phone: currentUserInfo.phone,
            email: currentUserInfo.email,
            idCard: currentUserInfo.id_card, // 从 userInfo.id_card 填充身份证号
            avatarFile: null
        };
        // 保存原始信息，用于比较
        originalPersonalInfo.value = {
            realName: currentUserInfo.real_name, // 注意这里是 real_name
            phone: currentUserInfo.phone,
            email: currentUserInfo.email,
            idCard: currentUserInfo.id_card, // 从 userInfo.id_card 保存原始身份证号
            avatarUrl: currentUserInfo.avatarUrl
        };
        // 设置当前头像预览
        personalInfoAvatarPreviewUrl.value = currentUserInfo.avatarUrl;
        // 打开对话框
        personalInfoDialogVisible.value = true;
    } else {
        ElMessage.error('无法获取个人信息，请重新登录。');
        router.push('/login');
    }
  } else if (command === 'logout') {
    try {
      await axios.post('/club/logout');
      localStorage.removeItem('token');
      localStorage.removeItem('role');
      localStorage.removeItem('userInfo');
      localStorage.removeItem("clubInfo");
      localStorage.removeItem('userId');
      ElMessage.success('已成功退出登录');
      router.push('/login');
    } catch (error) {
      console.error('登出失败:', error);
      ElMessage.error('登出操作失败，请重试或联系管理员');
      // 即便后端失败，前端也清理并跳转
      localStorage.removeItem('token');
      localStorage.removeItem('userInfo');
      localStorage.removeItem('clubInfo');
      localStorage.removeItem('role');
      localStorage.removeItem('username');
      localStorage.removeItem('avatarUrl');
      router.push('/login');
    }
  }
}

// 处理报名列表导出
const handleExportRegistrationCommand = async (command) => {
  if (selectedRegistrationIds.value.length === 0) {
    ElMessage.warning('请先选择要导出的报名记录');
    return;
  }

  ElMessage.info(`正在导出 ${command} 格式文件，请稍候...`);

  try {
    const response = await axios.post('/activities/exportRegistrations', {
      activityId: currentActivityId.value,
      userIds: selectedRegistrationIds.value,
      format: command
    }, {
      responseType: 'blob'
    });

    // 处理文件下载
    const blob = new Blob([response.data], { type: response.headers['content-type'] });
    const link = document.createElement('a');
    link.href = URL.createObjectURL(blob);

    // 尝试从响应头获取文件名，否则使用默认文件名
    const contentDisposition = response.headers['content-disposition'];
    let filename = `${currentActivityTitle}报名列表.${command}`;
    if (contentDisposition) {
      const utf8FilenameMatch = contentDisposition.match(/filename\*=UTF-8''([^;\n]*)/i);
      if (utf8FilenameMatch && utf8FilenameMatch[1]) {
        try {
          filename = decodeURIComponent(utf8FilenameMatch[1]);
        } catch (e) {
          console.error('Failed to decode UTF-8 filename', e);
          const standardFilenameMatch = contentDisposition.match(/filename="?([^"\n]*)"?/i);
          if (standardFilenameMatch && standardFilenameMatch[1]) {
            filename = standardFilenameMatch[1];
          }
        }
      } else {
        const standardFilenameMatch = contentDisposition.match(/filename="?([^"\n]*)"?/i);
        if (standardFilenameMatch && standardFilenameMatch[1]) {
          filename = standardFilenameMatch[1];
        }
      }
    }
    link.download = filename;
    link.click();

    // 清理
    URL.revokeObjectURL(link.href);
    ElMessage.success('文件导出成功');

  } catch (error) {
    console.error('批量导出失败:', error);
    if (error.response && error.response.data) {
      const reader = new FileReader();
      reader.onload = (e) => {
        try {
          const errorData = JSON.parse(e.target.result);
          ElMessage.error(errorData.message || '批量导出失败');
        } catch (parseError) {
          console.error('解析错误响应失败:', parseError);
          ElMessage.error('批量导出失败，服务器返回未知错误');
        }
      };
      if (error.response.data instanceof Blob) {
        reader.readAsText(error.response.data);
      } else {
        ElMessage.error('批量导出失败，无法解析服务器错误信息');
      }
    } else {
      ElMessage.error('批量导出网络错误');
    }
  }
};

// 搜索成员方法
const searchMembers = async (query) => {
  memberSearchLoading.value = true
  try {
    const response = await axios.post('/activities/selectClubsUser', {
      clubId: clubInfo.value.id,
      keyword: query
    })
    if (response.data.code === 200) {
      memberSearchList.value = response.data.data.map(member => ({
        userId: member.userId,
        username: member.username,
        realName: member.realName
      }))
    } else {
      memberSearchList.value = []
    }
  } catch (error) {
    console.error('搜索成员失败:', error)
    ElMessage.error('搜索成员失败')
    memberSearchList.value = []
  } finally {
    memberSearchLoading.value = false
  }
}


// 处理发布对话框
const handleOpenPublishDialog = (type, announcement = null) => {
  if (type === 'publish-draft' && announcement) {
    announcementForm.value = { ...announcement }
    dialogTitle.value = '发布公告'
  } else {
    // 新建时清空表单并设置默认发送方式
    announcementForm.value = {
      title: '',
      content: '',
      type: 'NOTICE',
      level: '社团级',
      sendType: 'broadcast', // 默认选中广播
      receiverIds: []
    }
    dialogTitle.value = '发布公告'
  }
  // 保证每次打开都默认选中广播
  if (!announcementForm.value.sendType) {
    announcementForm.value.sendType = 'broadcast'
  }
  announcementDialogVisible.value = true
}
// 搜索用户方法（照搬Admin.vue实现）
const searchUsers = async (query) => {
  userSearchLoading.value = true
  try {
    // 总是发送请求，即使query为空字符串
    const response = await axios.get('/admin/searchUsers', {
      params: {
        keyword: query
      }
    })
    if (response.data.code === 200) {
      // 只显示状态为启用且身份不是系统管理员的用户
      userSearchList.value = response.data.data.filter(user => user.status === 1 && user.role !== '系统管理员')
    } else {
      userSearchList.value = [] // 请求失败时清空列表
    }
  } catch (error) {
    console.error('搜索用户失败:', error)
    ElMessage.error('搜索用户失败')
    userSearchList.value = [] // 发生错误时清空列表
  } finally {
    userSearchLoading.value = false
  }
}

// 修改 saveAnnouncement 方法
const saveAnnouncement = async () => {
  try {
    // 表单验证
    if (!announcementForm.value.title) {
      ElMessage.error('公告标题不能为空')
      return
    }
    if (!announcementForm.value.content) {
      ElMessage.error('公告内容不能为空')
      return
    }
    if (!announcementForm.value.type) {
      ElMessage.error('请选择公告类型')
      return
    }
    if (announcementForm.value.sendType === 'multiple' && (!announcementForm.value.receiverIds || announcementForm.value.receiverIds.length === 0)) {
      ElMessage.error('请选择接收用户')
      return
    }

    const userId = JSON.parse(localStorage.getItem('userInfo'))?.id
    if (!userId) {
      ElMessage.error('无法获取当前用户ID，请重新登录')
      router.push('/login')
      return
    }

    // 如果是广播模式,获取社团所有成员的ID
    let receiverIds = []
    if (announcementForm.value.sendType === 'broadcast') {
      try {
        const response = await axios.get('/activities/selectClubsUserId', {
          params: {
            clubId: clubInfo.value.id
          }
        })
        if (response.data.code === 200) {
          receiverIds = response.data.data
        } else {
          throw new Error(response.data.message || '获取社团成员列表失败')
        }
      } catch (error) {
        console.error('获取社团成员列表失败:', error)
        ElMessage.error('获取社团成员列表失败')
        return
      }
    } else {
      receiverIds = announcementForm.value.receiverIds
    }

    // 构建请求体
    const payload = {
      id: announcementForm.value.id || null,
      title: announcementForm.value.title,
      content: announcementForm.value.content,
      type: announcementForm.value.type,
      level: '社团级',
      status: 1, // 发布时状态设为1
      senderId: parseInt(userId),
      receiverIds: receiverIds
    }

    // 根据是否有id决定调用创建还是更新接口
    const url = payload.id ? '/admin/updateAnnouncement' : '/admin/createAnnouncement'
    const response = await axios.post(url, payload)

    if (response.data.code === 200) {
      ElMessage.success(payload.id ? '公告更新成功' : '公告发布成功')
      announcementDialogVisible.value = false
      // 刷新公告列表
      searchAnnouncements()

      // 如果成功发布或更新，通过WebSocket发送消息
      if (connected.value) {
        // 根据用户输入和本地存储构建WebSocket消息
        const websocketMessage = {
          id: payload.id || response.data.data, // 如果是更新，使用原有id；如果是新建，使用返回的id
          title: announcementForm.value.title,
          content: announcementForm.value.content,
          type: announcementForm.value.type,
          level: announcementForm.value.level,
          senderId: parseInt(userId),
          receiverIds: receiverIds,
          sendTime: new Date().toISOString()
        }

        console.log('通过WebSocket发送公告消息:', websocketMessage)

        // 发送WebSocket消息
        stompClient.value.publish({
          destination: '/app/send',
          body: JSON.stringify(websocketMessage)
        })
      }
    } else {
      ElMessage.error(response.data.message || '操作失败')
    }
  } catch (error) {
    console.error('保存/发布公告失败:', error)
    ElMessage.error('操作失败：' + (error.response?.data?.message || error.message))
  }
}

// 添加获取角色标签类型的方法
const getRoleTagType = (role) => {
  switch (role) {
    case '系统管理员':
      return 'danger'
    case '社团管理员':
      return 'warning'
    case '普通用户':
      return 'info'
    default:
      return 'info'
  }
}

// 添加处理发送方式变化的方法
const handleSendTypeChange = (value) => {
  if (value === 'broadcast') {
    announcementForm.value.receiverIds = []
  }
}

// 新增创建草稿相关状态
const createDraftDialogVisible = ref(false)
const createDraftForm = ref({
  title: '',
  content: '',
  type: 'NOTICE',
  level: '社团级' // 创建草稿时固定为社团级
})

// 新增函数：打开创建公告草稿对话框
const handleOpenCreateDraftDialog = () => {
  createDraftForm.value = {
    title: '',
    content: '',
    type: 'NOTICE',
    level: '社团级'
  }
  createDraftDialogVisible.value = true
}

// 新增函数：保存草稿
const saveDraft = async () => {
  try {
    // 表单验证
    if (!createDraftForm.value.title) {
      ElMessage.error('公告标题不能为空')
      return
    }
    if (!createDraftForm.value.content) {
      ElMessage.error('公告内容不能为空')
      return
    }
    if (!createDraftForm.value.type) {
      ElMessage.error('请选择公告类型')
      return
    }
    if (createDraftForm.value.level !== '社团级') {
      // 以防万一还是验证一下内部值
      ElMessage.error('公告级别必须为社团级')
      return
    }

    // 构建请求体
    const payload = {
      title: createDraftForm.value.title,
      content: createDraftForm.value.content,
      type: createDraftForm.value.type,
      level: '社团级', // 级别固定为社团级
      status: 0, // 创建草稿状态设为0
      senderId: JSON.parse(localStorage.getItem('userInfo')).id // 添加创建者ID
    }

    const response = await axios.post('/admin/createAnnouncement', payload);

    if (response.data.code === 200) {
      ElMessage.success('草稿创建成功')
      createDraftDialogVisible.value = false
      // 刷新公告列表
      searchAnnouncements()
    } else {
      ElMessage.error(response.data.message || '创建失败')
    }
  } catch (error) {
    console.error('创建草稿失败:', error)
    ElMessage.error('操作失败：' + (error.response?.data?.message || error.message))
  }
}

// 社团信息编辑相关
const clubInfoDialogVisible = ref(false)
const clubInfoFormRef = ref(null)
const clubInfoForm = ref({
  clubId: null,
  clubName: '',
  clubDescription: '',
  activityStatus: '',
  clubCategory: '',
  maxMembers: 0,
  meetingTime: '',
  meetingLocation: '',
  contactPerson: '',
  contactEmail: '',
  clubAchievements: '',
  clubRegulations: ''
})
const clubLogoFile = ref(null)
const clubLogoPreviewUrl = ref('')

// 处理编辑社团信息按钮点击
const handleEditClubInfo = () => {
  clubInfoForm.value = {
    clubId: clubInfo.value.clubId,
    clubName: clubInfo.value.clubName,
    clubDescription: clubInfo.value.description,
    activityStatus: clubInfo.value.activity_status,
    clubCategory: clubInfo.value.category,
    maxMembers: clubInfo.value.maxMembers || 0,
    meetingTime: clubInfo.value.meetingTime,
    meetingLocation: clubInfo.value.meetingLocation,
    contactPerson: clubInfo.value.contactPerson,
    contactEmail: clubInfo.value.contactEmail,
    clubAchievements: clubInfo.value.achievements,
    clubRegulations: clubInfo.value.rules
  }
  clubLogoPreviewUrl.value = clubInfo.value.coverUrl
  clubLogoFile.value = null
  clubInfoDialogVisible.value = true
}

// 处理社团Logo上传
const handleClubLogoUpload = (file) => {
  if (file) {
    const isImage = file.raw.type.startsWith('image/')
    const isLt5M = file.raw.size / 1024 / 1024 < 5
    if (!isImage) {
      ElMessage.error('只能上传图片文件！')
      return false
    }
    if (!isLt5M) {
      ElMessage.error('图片大小不能超过 5MB！')
      return false
    }
    clubLogoFile.value = file.raw
    clubLogoPreviewUrl.value = URL.createObjectURL(file.raw)
    return true
  }
  return false
}

// 提交社团信息表单
const submitClubInfoForm = async () => {
  try {
    if (!clubInfoForm.value.clubId) {
      ElMessage.error('社团ID不能为空')
      return
    }

    const formData = new FormData()
    
    // 添加文件，如果用户没有上传新的Logo，则使用一个空文件
    if (clubLogoFile.value) {
      formData.append('file', clubLogoFile.value)
    } else {
      // 创建一个空的文件对象，后端会忽略它并保留原有的图片
      const emptyBlob = new Blob([''], { type: 'application/octet-stream' })
      formData.append('file', emptyBlob, 'empty.txt')
    }
    
    // 添加社团信息
    const clubInfoData = {
      clubId: clubInfoForm.value.clubId,
      clubName: clubInfoForm.value.clubName,
      clubDescription: clubInfoForm.value.clubDescription,
      activityStatus: clubInfoForm.value.activityStatus,
      clubCategory: clubInfoForm.value.clubCategory,
      maxMembers: clubInfoForm.value.maxMembers,
      meetingTime: clubInfoForm.value.meetingTime,
      meetingLocation: clubInfoForm.value.meetingLocation,
      contactPerson: clubInfoForm.value.contactPerson,
      contactEmail: clubInfoForm.value.contactEmail,
      clubAchievements: clubInfoForm.value.clubAchievements,
      clubRegulations: clubInfoForm.value.clubRegulations
    }
     // 打印请求体信息到控制台
     console.log('编辑社团信息请求体数据:', clubInfoData)
    // 使用JSON.stringify将对象转换为JSON字符串
    formData.append('literatureClub', new Blob([JSON.stringify(clubInfoData)], { type: 'application/json' }))
    
    const response = await axios.post('/activities/updateClubInfo', formData, {
      headers: { 'Content-Type': 'multipart/form-data' }
    })
    
    if (response.data.code === 200) {
      ElMessage.success('社团信息更新成功')
      clubInfoDialogVisible.value = false
      // 重新加载社团信息
      await loadClubInfo()
    } else {
      ElMessage.error(response.data.message || '更新社团信息失败')
    }
  } catch (error) {
    console.error('更新社团信息失败:', error)
    ElMessage.error('更新社团信息失败: ' + error.message)
  }
}

// ... existing code ...

// 活动详情相关
const activityDetailVisible = ref(false)
const currentActivity = ref(null)
const comments = ref([])
const newComment = ref('')
const replyContents = ref({})

// 查看活动详情
const handleViewActivity = async (activity) => {
  currentActivity.value = activity
  activityDetailVisible.value = true
  await loadComments(activity.id)
}

// 加载评论
const loadComments = async (activityId) => {
  try {
    const response = await axios.get(`/activities/comments/${activityId}`)
    if (response.data.code === 200) {
      // 从本地存储获取当前用户ID
      const currentUserId = JSON.parse(localStorage.getItem('userInfo'))?.id
      // 处理评论数据，添加作者标记
      comments.value = response.data.data.map(comment => ({
        ...comment,
        isAuthor: comment.userId === currentUserId // 使用本地存储的用户ID进行比对
      }))
    } else {
      ElMessage.error(response.data.message || '获取评论失败')
    }
  } catch (error) {
    console.error('获取评论失败:', error)
    ElMessage.error('获取评论失败')
  }
}

// 提交评论
const submitComment = async () => {
  if (!newComment.value.trim()) return
  
  try {
    const userInfo = JSON.parse(localStorage.getItem('userInfo'))
    if (!userInfo || !userInfo.id) {
      ElMessage.error('无法获取用户信息，请重新登录')
      return
    }

    const response = await axios.post('/activities/comments', {
      activityId: currentActivity.value.id,
      content: newComment.value.trim(),
      replierId: userInfo.id,
      parentId: null  // 主评论的 parentId 必须为 null
    })
    
    if (response.data.code === 200) {
      ElMessage.success('评论发布成功')
      newComment.value = ''
      await loadComments(currentActivity.value.id)
    } else {
      ElMessage.error(response.data.message || '评论发布失败')
    }
  } catch (error) {
    console.error('发布评论失败:', error)
    ElMessage.error('发布评论失败')
  }
}

// 提交回复
const submitReply = async (parentId) => {
  const content = replyContents.value[parentId]?.trim()
  if (!content) return
  
  try {
    const userInfo = JSON.parse(localStorage.getItem('userInfo'))
    if (!userInfo || !userInfo.id) {
      ElMessage.error('无法获取用户信息，请重新登录')
      return
    }
    console.log('parentId1:', parentId)
    const response = await axios.post('/activities/comments', {
      activityId: currentActivity.value.id,
      content: content,
      parentId: parentId,
      replierId: userInfo.id
    })
    console.log('parentId2:', parentId)
    if (response.data.code === 200) {
      ElMessage.success('回复发布成功')
      replyContents.value[parentId] = ''
      await loadComments(currentActivity.value.id)
    } else {
      ElMessage.error(response.data.message || '回复发布失败')
    }
  } catch (error) {
    console.error('发布回复失败:', error)
    ElMessage.error('发布回复失败')
  }
}

// ... existing code ...

// 获取被回复人的用户名
const getReplyToUser = (reply) => {
  if (!reply.parentId) return ''
  // 在所有评论和回复中查找 parentId 对应的评论
  const all = comments.value.flatMap(c => [c, ...(c.replies || [])])
  const parent = all.find(c => c.id === reply.parentId)
  return parent?.username || ''
}

// 添加处理嵌套回复的方法
const handleNestedReply = async (parentId, content) => {
  try {
    const userInfo = JSON.parse(localStorage.getItem('userInfo'))
    if (!userInfo || !userInfo.id) {
      ElMessage.error('无法获取用户信息，请重新登录')
      return
    }

    const response = await axios.post('/activities/comments', {
      activityId: currentActivity.value.id,
      content: content.trim(),
      parentId: parentId,
      replierId: userInfo.id
    })
    
    if (response.data.code === 200) {
      ElMessage.success('回复发布成功')
      // 刷新评论列表
      await loadComments(currentActivity.value.id)
    } else {
      ElMessage.error(response.data.message || '回复发布失败')
    }
  } catch (error) {
    console.error('发布回复失败:', error)
    ElMessage.error('发布回复失败')
  }
}

// 在 script setup 部分添加
const messageFilter = ref('all')

const handleMessageClick = (message) => {
  if (message && !message.readStatus) {
    // 处理单个消息点击，标记为已读
    markMessagesAsRead([message.id]);
    // 本地状态更新和未读计数减少将由 markMessagesAsRead 内部处理
  } else if (!message) {
    // 点击通知图标时，切换到消息管理页面
    activeMenu.value = 'message-management';
  }
  // 如果点击的是已读消息，不进行任何操作
}

// 添加标记消息为已读的API调用 (修改为支持单个或批量)
const markMessagesAsRead = async (messageIds) => {
  if (!messageIds || messageIds.length === 0) {
    console.warn('没有需要标记为已读的消息ID');
    return;
  }

  try {
    const userInfo = JSON.parse(localStorage.getItem('userInfo'))?.id;
    if (!userInfo) {
      ElMessage.error('无法获取用户信息，请重新登录');
      router.push('/login');
      return;
    }

    // 构建请求体对象，与后端的 DTO 对应
    const requestPayload = {
        messageIds: messageIds, // 传递消息ID列表
        adminId: userInfo
    };

    // 调用后端API更新消息状态，使用 POST 请求，将 requestPayload 作为请求体发送
    const response = await axios.post('/activities/updateMessageReadStatus', requestPayload /* , {
    //   headers: {
    //     'Content-Type': 'application/x-www-form-urlencoded' // Remove this header
    //   }
    } */);

    if (response.data.code === 200) {
      console.log('消息标记为已读成功:', messageIds);
      // 更新本地消息列表的状态
      messages.value.forEach(msg => {
        if (messageIds.includes(msg.id)) {
          msg.readStatus = 1;
        }
      });
      // 重新计算未读消息数量 (或者直接设置为 0 如果是全部标记已读)
      unreadMessageCount.value = messages.value.filter(msg => !msg.readStatus).length;
      // 如果是一键已读所有消息，可以直接设置 unreadMessageCount.value = 0;

    

    } else {
      ElMessage.error(response.data.message || '标记消息为已读失败');
    }
  } catch (error) {
    console.error('标记消息为已读失败:', error);
    ElMessage.error('标记消息为已读网络错误');
  }
}

// 新增一键已读方法
const handleMarkAllAsRead = async () => {
   // 过滤出所有未读消息的 ID
   const unreadIds = messages.value.filter(msg => !msg.readStatus).map(msg => msg.id);

   if (unreadIds.length === 0) {
     ElMessage.info('没有未读消息');
     return;
   }

   ElMessageBox.confirm(
    `确定将所有 ${unreadIds.length} 条未读消息标记为已读吗?`,
    '提示',
    {
      confirmButtonText: '确定',
      cancelButtonText: '取消',
      type: 'warning',
    }
  ).then(async () => {
    // 调用标记消息为已读的函数，传递未读ID列表
    await markMessagesAsRead(unreadIds);
    // 标记成功后立即刷新消息列表
    await loadMessages();
    ElMessage.success('所有消息已标记为已读');

  }).catch(() => {
    ElMessage.info('已取消操作');
  });
}

// 添加加载消息列表的方法
const loadMessages = async () => {
  try {
    const userInfo = JSON.parse(localStorage.getItem('userInfo'));
    const adminId = userInfo?.id;

    if (!adminId) {
      ElMessage.error('无法获取管理员ID，请重新登录');
      router.push('/login');
      return;
    }

    let readStatusParam = null;
    if (messageFilter.value === 'unread') {
      readStatusParam = 0;
    } else if (messageFilter.value === 'read') {
      readStatusParam = 1;
    }

    const params = {
      adminId: adminId,
      readStatus: readStatusParam
    };

    const response = await axios.get('/activities/messages', {
      params: params
    });

    if (response.data.code === 200) {
      messages.value = response.data.data;
      // 确保每条消息都有 readStatus 字段，并计算未读消息数量
      messages.value = messages.value.map(msg => ({
        ...msg,
        readStatus: msg.readStatus === undefined ? 1 : msg.readStatus // 默认认为已读如果未定义
      }))
      unreadMessageCount.value = messages.value.filter(msg => !msg.readStatus).length;
      // 使用 nextTick 确保 DOM 更新
      nextTick(() => {
        console.log('Messages updated and DOM should be re-rendered.');
      });
    } else {
      ElMessage.error(response.data.message || '获取消息列表失败');
      messages.value = [];
      unreadMessageCount.value = 0;
    }
  } catch (error) {
    console.error('获取消息列表失败:', error);
    ElMessage.error('获取消息列表网络错误');
    messages.value = [];
    unreadMessageCount.value = 0;
  }
}

// 监听 messageFilter 的变化，重新加载消息
watch(messageFilter, (newValue, oldValue) => {
  if (newValue !== oldValue) {
    loadMessages();
  }
});

// 添加未读消息计数
const unreadMessageCount = ref(0)

// 添加消息通知相关的状态
const notifications = ref([])

// 获取通知图标
const getNotificationIcon = (type) => {
  switch (type) {
    case 'ANNOUNCEMENT':
    case 'NOTICE': // 添加 NOTICE 类型映射到 Bell
      return 'Bell'
    case 'EVENT':
      return 'Calendar'
    default:
      return 'Message'
  }
}

// 新增：处理个人信息头像上传
const handlePersonalInfoAvatarUpload = (file) => {
  if (file) {
    const isImage = file.raw.type.startsWith('image/')
    const isLt5M = file.raw.size / 1024 / 1024 < 5
    if (!isImage) {
      ElMessage.error('只能上传图片文件！')
      personalInfoForm.value.avatarFile = null; // 清空文件
      personalInfoAvatarPreviewUrl.value = originalPersonalInfo.value.avatarUrl; // 恢复原头像预览，使用原始头像URL
      return false;
    }
    if (!isLt5M) {
      ElMessage.error('图片大小不能超过 5MB！')
      personalInfoForm.value.avatarFile = null; // 清空文件
      personalInfoAvatarPreviewUrl.value = originalPersonalInfo.value.avatarUrl; // 恢复原头像预览，使用原始头像URL
      return false;
    }
    personalInfoForm.value.avatarFile = file.raw;
    personalInfoAvatarPreviewUrl.value = URL.createObjectURL(file.raw);
    return true;
  }
  personalInfoForm.value.avatarFile = null; // 清空文件
  personalInfoAvatarPreviewUrl.value = originalPersonalInfo.value.avatarUrl; // 恢复原头像预览，使用原始头像URL
  return false;
};


const uploadAvatar = async (file) => {
    try {
        const formData = new FormData();
        formData.append('file', file);
        const response = await axios.post('/activities/uploadAvatar', formData, {
            headers: { 'Content-Type': 'multipart/form-data' }
        });
        if (response.data.code === 200 && response.data.data && response.data.data.url) {
            ElMessage.success('头像上传成功');
            return response.data.data.url; // 返回上传成功后的文件URL
        } else {
            ElMessage.error(response.data.message || '头像上传失败');
            return null;
        }
    } catch (error) {
        console.error('头像上传网络错误:', error);
        ElMessage.error('头像上传网络错误');
        return null;
    }
};

// 新增：提交个人信息表单
const submitPersonalInfoForm = async () => {
  try {
    const formData = new FormData();
    
    // 构建更新请求对象
    const updatePayload = {
      userId: personalInfoForm.value.userId,
      realName: personalInfoForm.value.realName !== originalPersonalInfo.value.realName ? personalInfoForm.value.realName : null,
      phone: personalInfoForm.value.phone !== originalPersonalInfo.value.phone ? personalInfoForm.value.phone : null,
      email: personalInfoForm.value.email !== originalPersonalInfo.value.email ? personalInfoForm.value.email : null,
      idCard: personalInfoForm.value.idCard !== originalPersonalInfo.value.idCard ? personalInfoForm.value.idCard : null, // 添加身份证号
      originalAvatarUrl: originalPersonalInfo.value.avatarUrl // 添加原始头像URL
    };

    // 添加文件（如果有）
    if (personalInfoForm.value.avatarFile) {
      formData.append('file', personalInfoForm.value.avatarFile);
    }

    // 添加更新请求对象
    formData.append('updatePersonalInfoRequestDto', new Blob([JSON.stringify(updatePayload)], { type: 'application/json' }));

    const response = await axios.post('/activities/updatePersonalInfo', formData, {
      headers: { 'Content-Type': 'multipart/form-data' }
    });

    if (response.data.code === 200) {
      ElMessage.success('个人信息更新成功');
      personalInfoDialogVisible.value = false;
      
      // 更新本地存储的用户信息
      const updatedUserInfo = JSON.parse(localStorage.getItem('userInfo'));
      if (updatePayload.realName !== null) updatedUserInfo.real_name = updatePayload.realName;
      if (updatePayload.phone !== null) updatedUserInfo.phone = updatePayload.phone;
      if (updatePayload.email !== null) updatedUserInfo.email = updatePayload.email;
      if (updatePayload.idCard !== null) updatedUserInfo.id_card = updatePayload.idCard; // 更新本地存储的身份证号
      if (response.data.data && response.data.data.avatarUrl) {
        updatedUserInfo.avatarUrl = response.data.data.avatarUrl;
      }

      localStorage.setItem('userInfo', JSON.stringify(updatedUserInfo));
      userInfo.value = updatedUserInfo;
      personalInfoAvatarPreviewUrl.value = userInfo.value.avatarUrl;
      personalInfoForm.value.avatarFile = null;
    } else {
      ElMessage.error(response.data.message || '更新个人信息失败');
    }
  } catch (error) {
    console.error('更新个人信息失败:', error);
    ElMessage.error('更新个人信息网络错误');
  }
};

// 添加审核结果对话框的响应式变量
const reviewResultDialogVisible = ref(false)
const reviewResult = ref({
  maxParticipants: 0,
  currentApplicants: 0,
  remainingSpots: 0,
  reviewedCount: 0
})

</script>

<style scoped>
.club-admin-dashboard {
  min-height: 100vh;
  background: linear-gradient(135deg, #f7fafc 0%, #e3f6f5 100%);
  display: flex;
  flex-direction: column;
  overflow: hidden;
}

.full-height {
  height: 100%;
  flex-grow: 1;
}

.dashboard-header {
  background: linear-gradient(90deg, #8fd6e1 0%, #b8e1dd 100%);
  color: #22577a;
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding: 0 32px;
  height: 64px;
  box-shadow: 0 2px 12px rgba(100, 200, 180, 0.08);
  border-bottom: 1.5px solid #e3e8ee;
  flex-shrink: 0;
  z-index: 100;
}

.header-title {
  font-size: 22px;
  font-weight: bold;
  letter-spacing: 1.5px;
}

.header-user {
  display: flex;
  align-items: center;
  gap: 20px;
}

.header-user .user-info {
  display: flex;
  align-items: center;
  cursor: pointer;
  padding: 6px 16px;
  border-radius: 20px;
  background: rgba(255, 255, 255, 0.7);
  box-shadow: 0 2px 8px rgba(100, 200, 180, 0.08);
  transition: background 0.3s;
}

.header-user .user-info:hover {
  background: #e3f6f5;
}

.header-user .username {
  font-weight: 500;
  font-size: 15px;
  color: #22577a;
}

.el-avatar {
  border: 2px solid #b8e1dd;
  box-shadow: 0 2px 8px rgba(100, 200, 180, 0.10);
}

.main-container {
  flex-grow: 1;
  overflow: hidden;
}

.sidebar-menu {
  background: #f7fafc;
  height: 100%;
  box-shadow: 2px 0 8px rgba(100, 200, 180, 0.04);
}

.sidebar-menu .el-menu-vertical {
  border-right: none;
  padding: 24px 0;
  background: transparent;
}

.sidebar-menu .el-menu-item {
  font-size: 15px;
  height: 48px;
  line-height: 48px;
  margin: 10px 0;
  padding: 0 24px !important;
  border-radius: 12px;
  color: #22577a;
  transition: background 0.2s, color 0.2s;
}

.sidebar-menu .el-menu-item .el-icon {
  margin-right: 10px;
  font-size: 18px;
  vertical-align: middle;
}

.sidebar-menu .el-menu-item span {
  vertical-align: middle;
}

.sidebar-menu .el-menu-item:hover {
  background: #e3f6f5 !important;
  color: #38a3a5 !important;
}

.sidebar-menu .el-menu-item.is-active {
  background: linear-gradient(90deg, #8fd6e1 0%, #b8e1dd 100%) !important;
  color: #22577a !important;
  font-weight: bold;
}

.sidebar-menu .el-menu-item.is-active::before {
  content: '';
  position: absolute;
  left: 0;
  top: 0;
  bottom: 0;
  width: 3px;
  background: #38a3a5;
}

.content-area {
  background: transparent;
  padding: 32px;
  height: 100%;
  overflow-y: auto;
}

.content-section .box-card {
  border-radius: 16px;
  border: 1.5px solid #e3e8ee;
  box-shadow: 0 4px 24px 0 rgba(100, 200, 180, 0.10);
  margin-bottom: 28px;
  background: #fff;
  transition: box-shadow 0.2s;
}

.content-section .box-card:hover {
  box-shadow: 0 8px 32px 0 rgba(100, 200, 180, 0.18);
}

.card-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding: 18px 24px;
  border-bottom: 1px solid #ebeef5;
  background: #f7fafc;
  border-radius: 16px 16px 0 0;
}

.card-title {
  font-size: 17px;
  font-weight: bold;
  white-space: nowrap;
  flex-shrink: 0;
  margin-right: 20px;
}

.header-operations {
  flex: 1;
  display: flex;
  align-items: center;
  justify-content: flex-end;
  gap: 16px;
}

.search-form {
  flex-shrink: 0;
}

.search-form :deep(.el-form) {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 8px;
  margin-bottom: 0;
}

.search-form :deep(.el-form-item) {
  margin-bottom: 0;
  margin-right: 0;
}

.card-header .el-button .el-icon {
  font-size: 14px;
}

.el-table {
  font-size: 14px;
  margin-top: 18px;
  border-radius: 12px;
  overflow: hidden;
  background: #fafdff;
  box-shadow: 0 2px 8px rgba(100, 200, 180, 0.06);
}

.el-table th.el-table__cell {
  background: #e3f6f5 !important;
  color: #22577a;
  font-weight: bold;
  font-size: 15px;
}

.el-table td.el-table__cell,
.el-table th.el-table__cell {
  padding: 12px 0;
}

.el-table .el-button--small {
  font-size: 13px;
}

.el-table .el-button+.el-button {
  margin-left: 8px;
}

.el-descriptions {
  padding: 10px 20px 20px 20px;
}

:deep(.desc-label) {
  font-weight: normal;
  color: #555;
  background: #e3f6f5 !important;
  width: 120px;
}

:deep(.desc-content) {
  color: #333;
}

.el-dialog__header {
  padding: 16px 24px;
  margin-right: 0;
  border-bottom: 1px solid #f0f0f0;
}

.el-dialog__title {
  font-size: 17px;
  font-weight: 500;
}

.el-dialog__body {
  padding: 20px 24px;
}

.el-dialog__footer {
  padding: 12px 24px;
  border-top: 1px solid #f0f0f0;
}

.activity-cover-preview {
  width: 180px;
  height: 180px;
  object-fit: cover;
  border-radius: 8px;
  border: 1.5px solid #e3e8ee;
  display: block;
}

.batch-actions {
  display: flex;
  align-items: center;
  gap: 12px;
  margin-right: 16px;
  padding: 8px 16px;
  background: #f5f7fa;
  border-radius: 4px;
  border: 1px solid #e4e7ed;
}

.selected-count {
  color: #606266;
  font-size: 13px;
  margin-left: 8px;
}

.header-operations {
  display: flex;
  align-items: center;
  gap: 16px;
}

.el-table .el-table__header-wrapper th {
  background: #e3f6f5;
}

.el-table .el-table__row:hover {
  background: #f5f7fa;
}

.el-table .el-table__row.is-selected {
  background: #ecf5ff !important;
}

.el-table .el-button-group {
  display: flex;
  gap: 8px;
}

.el-table .cell {
  display: flex;
  align-items: center;
  justify-content: center;
}

.el-table .el-button+.el-button {
  margin-left: 8px;
}

.el-tag {
  border-radius: 6px;
  padding: 0 10px;
  height: 26px;
  line-height: 26px;
  font-size: 14px;
}

.el-input,
.el-select {
  border-radius: 8px;
  min-width: 120px;
}

.el-input__inner,
.el-select .el-input__inner {
  border-radius: 8px !important;
}

.el-button {
  border-radius: 8px;
  padding: 8px 20px;
  font-weight: 500;
  font-size: 15px;
  transition: all 0.3s;
}

.el-button:hover {
  transform: translateY(-2px);
  box-shadow: 0 2px 8px rgba(100, 200, 180, 0.12);
}

.el-button--primary {
  background: linear-gradient(90deg, #8fd6e1 0%, #b8e1dd 100%);
  border: none;
  color: #22577a;
}

.el-button--primary:hover {
  background: linear-gradient(90deg, #b8e1dd 0%, #8fd6e1 100%);
  color: #38a3a5;
}

.el-button--success {
  background: linear-gradient(90deg, #b7e4c7 0%, #d8f3dc 100%);
  border: none;
  color: #40916c;
}

.el-button--success:hover {
  background: linear-gradient(90deg, #d8f3dc 0%, #b7e4c7 100%);
  color: #52b788;
}

.el-button--danger {
  background: linear-gradient(90deg, #ffb4a2 0%, #ffdac1 100%);
  border: none;
  color: #b0413e;
}

.el-button--danger:hover {
  background: linear-gradient(90deg, #ffdac1 0%, #ffb4a2 100%);
  color: #e76f51;
}

.el-button--warning {
  background: linear-gradient(90deg, #ffe066 0%, #ffd166 100%);
  border: none;
  color: #b08900;
}

.el-button--warning:hover {
  background: linear-gradient(90deg, #ffd166 0%, #ffe066 100%);
  color: #e9c46a;
}

.el-dropdown-menu {
  border-radius: 10px;
  box-shadow: 0 2px 12px rgba(100, 200, 180, 0.10);
  padding: 4px 0;
}

.el-dropdown-menu__item {
  padding: 10px 20px;
  font-size: 15px;
}

.el-dropdown-menu__item:hover {
  background: #e3f6f5;
}

::-webkit-scrollbar {
  width: 8px;
  background: #e3f6f5;
}

::-webkit-scrollbar-thumb {
  background: #b8e1dd;
  border-radius: 4px;
}

.publish-btn {
  background: linear-gradient(90deg, #8fd6e1 0%, #b8e1dd 100%);
  color: #22577a;
  border: none;
  border-radius: 16px;
  margin-right: 10px;
  font-weight: bold;
  transition: all 0.2s;
}

.publish-btn:hover {
  background: linear-gradient(90deg, #b8e1dd 0%, #8fd6e1 100%);
  color: #38a3a5;
}

.delete-btn {
  background: linear-gradient(90deg, #ffb4a2 0%, #ffdac1 100%);
  color: #b0413e;
  border: none;
  border-radius: 16px;
  font-weight: bold;
  transition: all 0.2s;
}

.delete-btn:hover {
  background: linear-gradient(90deg, #ffdac1 0%, #ffb4a2 100%);
  color: #e76f51;
}

.pagination {
  margin-top: 24px;
  display: flex;
  justify-content: center;
  padding: 16px 0;
}

.club-logo-preview {
  width: 180px;
  height: 180px;
  object-fit: cover;
  border-radius: 8px;
  border: 1.5px solid #e3e8ee;
  display: block;
}

/* 活动详情样式 */
.activity-detail-dialog .activity-detail .activity-header {
  display: flex;
  align-items: center;
  gap: 16px;
  margin-bottom: 24px;
}

.activity-detail-dialog .activity-detail .activity-header h2 {
  margin: 0;
  color: #22577a;
}

.activity-detail-dialog .activity-detail .activity-content {
  display: flex;
  gap: 24px;
  margin-bottom: 32px;
}

.activity-detail-dialog .activity-detail .activity-content .activity-cover {
  flex: 0 0 300px;
}

.activity-detail-dialog .activity-detail .activity-content .activity-cover .el-image {
  width: 100%;
  height: 200px;
  border-radius: 8px;
  overflow: hidden;
}

.activity-detail-dialog .activity-detail .activity-content .activity-info {
  flex: 1;
}

.activity-detail-dialog .activity-detail .activity-comments {
  margin-top: 32px;
}

.activity-detail-dialog .activity-detail .activity-comments h3 {
  margin-bottom: 16px;
  color: #22577a;
}

.activity-detail-dialog .activity-detail .activity-comments .comment-form {
  margin-bottom: 24px;
}

.activity-detail-dialog .activity-detail .activity-comments .comment-form .el-button {
  margin-top: 12px;
}

.activity-detail-dialog .activity-detail .activity-comments .comment-list .comment-item {
  padding: 16px;
  border-bottom: 1px solid #e3e8ee;
}

.activity-detail-dialog .activity-detail .activity-comments .comment-list .comment-item .comment-header {
  display: flex;
  align-items: center;
  gap: 12px;
  margin-bottom: 12px;
}

.activity-detail-dialog .activity-detail .activity-comments .comment-list .comment-item .comment-header .comment-info {
  display: flex;
  flex-direction: column;
}

.activity-detail-dialog .activity-detail .activity-comments .comment-list .comment-item .comment-header .comment-info .username {
  font-weight: 500;
  color: #22577a;
}

.activity-detail-dialog .activity-detail .activity-comments .comment-list .comment-item .comment-header .comment-info .time {
  font-size: 12px;
  color: #909399;
}

.activity-detail-dialog .activity-detail .activity-comments .comment-list .comment-item .comment-content {
  margin: 12px 0;
  color: #333;
}

.activity-detail-dialog .activity-detail .activity-comments .comment-list .comment-item .reply-list {
  margin-left: 52px;
  margin-top: 12px;
}

.activity-detail-dialog .activity-detail .activity-comments .comment-list .comment-item .reply-list .reply-item {
  padding: 12px;
  background: #f5f7fa;
  border-radius: 8px;
  margin-bottom: 8px;
}

.activity-detail-dialog .activity-detail .activity-comments .comment-list .comment-item .reply-list .reply-item .reply-header {
  display: flex;
  align-items: center;
  gap: 8px;
  margin-bottom: 8px;
}

.activity-detail-dialog .activity-detail .activity-comments .comment-list .comment-item .reply-list .reply-item .reply-header .reply-info {
  display: flex;
  flex-direction: column;
}

.activity-detail-dialog .activity-detail .activity-comments .comment-list .comment-item .reply-list .reply-item .reply-header .reply-info .username {
  font-weight: 500;
  color: #22577a;
}

.activity-detail-dialog .activity-detail .activity-comments .comment-list .comment-item .reply-list .reply-item .reply-header .reply-info .time {
  font-size: 12px;
  color: #909399;
  margin-top: 2px;
}

.activity-detail-dialog .activity-detail .activity-comments .comment-list .comment-item .reply-list .reply-item .reply-content {
  color: #333;
}

.activity-detail-dialog .activity-detail .activity-comments .comment-list .comment-item .reply-form {
  margin-left: 52px;
  margin-top: 12px;
}

.activity-detail-dialog .activity-detail .activity-comments .comment-list .comment-item .reply-form .el-button {
  margin-top: 8px;
}

/* 评论区域样式更新 */
.activity-comments {
  margin-top: 32px;
  padding: 24px;
  background: #fff;
  border-radius: 12px;
  box-shadow: 0 2px 12px rgba(0, 0, 0, 0.04);
}

.activity-comments h3 {
  margin-bottom: 24px;
  color: #22577a;
  font-size: 18px;
  font-weight: 600;
}

.comment-form {
  margin-bottom: 32px;
}

.comment-form .el-button {
  margin-top: 12px;
}

.comment-list .comment-item {
  padding: 20px;
  border-bottom: 1px solid #ebeef5;
}

.comment-list .comment-item:last-child {
  border-bottom: none;
}

.comment-header {
  display: flex;
  align-items: center;
  gap: 12px;
  margin-bottom: 12px;
}

.comment-info {
  display: flex;
  flex-direction: column;
}

.comment-info .username {
  font-weight: 500;
  color: #22577a;
  font-size: 15px;
}

.comment-info .time {
  font-size: 12px;
  color: #909399;
  margin-top: 4px;
}

.comment-content {
  margin: 12px 0;
  color: #333;
  font-size: 14px;
  line-height: 1.6;
}

.reply-list {
  margin-left: 52px;
  margin-top: 16px;
}

.reply-item {
  padding: 16px;
  background: #f5f7fa;
  border-radius: 8px;
  margin-bottom: 12px;
}

.reply-header {
  display: flex;
  align-items: center;
  gap: 8px;
  margin-bottom: 8px;
}

.reply-info {
  display: flex;
  flex-direction: column;
}

.reply-info .username {
  font-weight: 500;
  color: #22577a;
  font-size: 14px;
}

.reply-info .time {
  font-size: 12px;
  color: #909399;
  margin-top: 2px;
}

.reply-content {
  color: #333;
  font-size: 14px;
  line-height: 1.5;
}

.nested-replies {
  margin-left: 38px;
  margin-top: 12px;
}

.nested-reply-item {
  padding: 12px;
  background: #fff;
  border-radius: 6px;
  margin-bottom: 8px;
  border: 1px solid #ebeef5;
}

.nested-reply-header {
  display: flex;
  align-items: center;
  gap: 8px;
  margin-bottom: 6px;
}

.nested-reply-info {
  display: flex;
  flex-direction: column;
}

.nested-reply-info .username {
  font-weight: 500;
  color: #22577a;
  font-size: 13px;
}

.nested-reply-info .time {
  font-size: 11px;
  color: #909399;
  margin-top: 2px;
}

.nested-reply-content {
  color: #333;
  font-size: 13px;
  line-height: 1.5;
}

.reply-form {
  margin-left: 52px;
  margin-top: 16px;
}

.reply-form .el-button {
  margin-top: 8px;
}

.message-list {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(300px, 1fr));
  gap: 20px;
  padding: 20px;
  max-height: 600px; /* 设置最大高度 */
  overflow-y: auto; /* 内容超出时显示垂直滚动条 */
}

.message-card {
  background: #fff;
  border-radius: 12px;
  padding: 20px;
  cursor: pointer;
  transition: all 0.3s ease;
  border: 1px solid #ebeef5;
  display: flex;
  gap: 16px;
  position: relative;
  overflow: hidden;
}

.message-card:hover {
  transform: translateY(-2px);
  box-shadow: 0 4px 12px rgba(0, 0, 0, 0.1);
}

.message-card.unread {
  background: #f0f9ff;
  border-left: 4px solid #409eff;
}

.message-icon {
  width: 48px;
  height: 48px;
  border-radius: 12px;
  display: flex;
  align-items: center;
  justify-content: center;
  flex-shrink: 0;
}

.message-icon.announcement {
  background: linear-gradient(135deg, #ffd666 0%, #ffa940 100%);
  color: #fff;
}

.message-icon.activity {
  background: linear-gradient(135deg, #95de64 0%, #52c41a 100%);
  color: #fff;
}

.message-content {
  flex: 1;
  min-width: 0;
}

.message-header {
  display: flex;
  justify-content: space-between;
  align-items: flex-start;
  margin-bottom: 8px;
}

.message-title {
  font-weight: 600;
  color: #1f2937;
  font-size: 16px;
  margin-right: 8px;
  flex: 1;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.message-body {
  color: #4b5563;
  font-size: 14px;
  line-height: 1.5;
  margin-bottom: 12px;
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;
}

.message-footer {
  display: flex;
  justify-content: space-between;
  align-items: center;
  font-size: 12px;
  color: #6b7280;
}

.unread-badge {
  background: #409eff;
  color: #fff;
  padding: 2px 8px;
  border-radius: 10px;
  font-size: 12px;
}

.message-filters {
  margin-left: auto;
}

.message-filters .el-radio-group {
  background: #f5f7fa;
  padding: 4px;
  border-radius: 8px;
}

.message-filters .el-radio-button__inner {
  border: none;
  padding: 8px 16px;
}

.message-filters .el-radio-button__original-radio:checked + .el-radio-button__inner {
  background: #fff;
  box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
}

.message-notification {
  cursor: pointer;
  padding: 8px;
  border-radius: 50%;
  transition: all 0.3s ease;
  display: flex;
  align-items: center;
  justify-content: center;
}

.message-notification:hover {
  background: rgba(255, 255, 255, 0.3);
}

.message-icon {
  font-size: 20px;
  color: #22577a;
}

.message-badge :deep(.el-badge__content) {
  background: #ff4d4f;
  border: none;
  font-size: 12px;
  height: 16px;
  padding: 0 4px;
  line-height: 16px;
  border-radius: 8px;
  transform: translate(50%, -50%);
}

.message-badge :deep(.el-badge__content.is-fixed) {
  top: 4px;
  right: 4px;
}

/* 消息通知样式 */
.message-notifications {
  position: fixed;
  top: 80px;
  right: 20px;
  z-index: 9999;
  display: flex;
  flex-direction: column;
  gap: 10px;
}

.notification-item {
  min-width: 300px;
  max-width: 400px;
}

.notification-content {
  background: white;
  border-radius: 8px;
  padding: 16px;
  box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15);
  display: flex;
  align-items: flex-start;
  gap: 12px;
  border-left: 4px solid;
}

.notification-content.announcement {
  border-left-color: #ffa940;
}

.notification-content.event {
  border-left-color: #52c41a;
}

.notification-content.system {
  border-left-color: #1890ff;
}

/* 为 NOTICE 类型添加样式 */
.notification-content.notice {
  border-left-color: #409eff; /* 使用一个蓝色系，可以根据需要调整 */
}

.notification-icon {
  font-size: 20px;
  padding: 8px;
  border-radius: 8px;
  /* Remove or override the fixed background color here */
  /* background: #f5f5f5; */
}

.notification-content.announcement .notification-icon {
  color: #ffa940;
  background-color: #fff7e6; /* 浅橙色背景 */
}

.notification-content.event .notification-icon {
  color: #52c41a;
  background-color: #f6ffed; /* 浅绿色背景 */
}

.notification-content.system .notification-icon {
  color: #1890ff;
  background-color: #e6f7ff; /* 浅蓝色背景 */
}

.notification-content.notice .notification-icon {
  color: #409eff; /* 使用一个蓝色系，可以根据需要调整 */
  background-color: #e6feff; /* 浅蓝色背景，与 notice 边框颜色搭配 */
}

.notification-info {
  flex: 1;
}

.notification-title {
  font-weight: 600;
  color: #1f2937;
  margin-bottom: 4px;
}

.notification-message {
  color: #4b5563;
  font-size: 14px;
}

/* 消息动画 */
.message-slide-enter-active,
.message-slide-leave-active {
  transition: all 0.3s ease;
}

.message-slide-enter-from {
  opacity: 0;
  transform: translateX(100%);
}

.message-slide-leave-to {
  opacity: 0;
  transform: translateX(100%);
}

.message-slide-move {
  transition: transform 0.3s ease;
}

.review-result-content {
  padding: 20px;
}

.review-result-content :deep(.el-descriptions__label) {
  width: 140px;
  font-weight: bold;
}

.review-result-content :deep(.el-descriptions__content) {
  text-align: center;
}

.review-result-display {
  margin-bottom: 20px;
  padding: 15px;
  background-color: #f7fafc; /* 浅背景色 */
  border: 1px solid #e3e8ee;
  border-radius: 8px;
  box-shadow: 0 1px 6px rgba(0, 0, 0, 0.05);
}

.review-result-display :deep(.el-descriptions__header) {
  margin-bottom: 10px;
}

.review-result-display :deep(.el-descriptions__title) {
  font-size: 16px;
  font-weight: bold;
  color: #22577a;
}

.review-result-display :deep(.el-descriptions__label) {
  font-weight: normal;
  color: #555;
  background-color: #e3f6f5 !important; /* 浅绿色背景 */
  width: 120px;
}

.review-result-display :deep(.el-descriptions__content) {
  text-align: center;
  color: #333;
}
</style>